diff --git a/.cvsignore b/.cvsignore
index 38b6258c..5f4ab297 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,15 +1,14 @@
-CVS/
-/contrib/include/
-/defunct/
-/EXTRA/
-/doc/
+contrib/include
+defunct
+EXTRA
+doc
/win32/Autoupdater/
-/objects/
-/lib/
-/bin/
-/macros/
-/help/
-/.makelib/
+objects.*
+lib.*
+bin.*
+macros
+help
+.makelib
_grstate
.created
.unpacked*
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ab78dd41..a3336ac4 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -8,49 +8,60 @@ jobs:
matrix:
os: [windows-latest, ubuntu-latest]
steps:
- - uses: actions/checkout@v2
-
+ - uses: actions/checkout@v2
+
- uses: ilammy/msvc-dev-cmd@v1
if: runner.os == 'Windows'
with:
arch: x86
+
+ - uses: msys2/setup-msys2@v2
+ if: runner.os == 'Windows'
+ with:
+ release: false
+ update: true
+ install: >-
+ bison
+
- name: Windows, generating Makefiles
if: runner.os == 'Windows'
shell: cmd
run: |
@set PERL=c:/Strawberry/perl/bin/perl
- c:/Strawberry/perl/bin/perl makelib.pl --perlpath=c:/Strawberry/perl/bin --busybox=./win32/busybox --wget=./win32/wget --bison=c:/msys64/usr/bin/bison --flex=./bin/flex --verbose vc2019
+ c:/Strawberry/perl/bin/perl makelib.pl --perlpath=c:/Strawberry/perl/bin --busybox=./win32/busybox --wget=./win32/wget --bison=c:/msys64/usr/bin/bison --flex=./bin/flex --verbose vc2022
@rem dir c:\tools
@rem dir c:\msys64
@rem dir c:\msys64\usr\bin
+
- name: Windows, compiling
if: runner.os == 'Windows'
shell: cmd
run: |
@set PERL=c:/Strawberry/perl/bin/perl
- .\win32\gmake-42 contrib
- .\win32\gmake-42
+ .\win32\gmake-42 release contrib
+ .\win32\gmake-42 release
+
- name: Windows, package
if: runner.os == 'Windows'
uses: actions/upload-artifact@v2
with:
name: package-win32
- path: ./bin.vs160/debug/*
+ path: ./bin.vs170/debug/*
- name: Linux, generating Makefiles
if: runner.os == 'Linux'
shell: bash
run: |
- ./support/config_withncurses
+ ./support/config_withncurses
- name: Linux, compiling
if: runner.os == 'Linux'
shell: bash
run: |
- make
+ make release
- name: Linux, package
if: runner.os == 'Linux'
uses: actions/upload-artifact@v2
with:
name: package-linux
path: ./bin.gcc/debug/*
-
+
diff --git a/.gitignore b/.gitignore
index 04b37a70..d4e2ff67 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,28 +1,42 @@
CVS/
-/contrib/include/
-/win32/Autoupdater/
-/defunct/
-/EXTRA/
-/doc/
-/objects/
-/lib/
-/bin/
-/macros/
-/help/
-/.makelib/
+defunct/
+.makelib/
+contrib/include/
+win32/Autoupdater/
+EXTRA/
+doc/
+bin
+bin.*/
+lib.*/
+objects*/
+macros/
+help/
+Makefile
GIT_Notes.txt
GIT*.bat
_grstate
.created
.unpacked*
__libtool__.lnk
-Makefile
+.#*
*.cache
*.exe
*.dll
*.pdb
*.obj
+*.o
*.cm
*.bak
+*.a
+*.lo
+*.la
+*~
*.err
-.#*
+*.mbr
+*.log
+*.old
+*.sav
+*.bak
+*.orig
+*.org
+*.bat
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..51054403
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "win32/libappupdater"]
+ path = win32/libappupdater
+ url = https://github.com/adamyg/libappupdater
diff --git a/BUILDNUMBER.in b/BUILDNUMBER.in
index d6b24041..2bd5a0a9 100644
--- a/BUILDNUMBER.in
+++ b/BUILDNUMBER.in
@@ -1 +1 @@
-19
+22
diff --git a/Changes b/Changes
index 844941b3..6e0accfd 100644
--- a/Changes
+++ b/Changes
@@ -1,7 +1,34 @@
-*- encoding: utf-8; -*-
+Tue Mar 22 18:46:50 2022 adamy
+
+ * BUILD 21, version: 3.2.2
+
+ * libw32 merge.
+
+Mon Jul 12 22:52:00 2021 adamy
+
+ * echo-line winch handling.
+
+ * width-character
+
+ o wcwidth(), set_unique_version() and inq_unicode_version() primitives.
+ o wxxx() primitives().
+ o %S and %W printf formats.
+ o buffer insertion primitives (insert() and insertf()) return width not characters.
+ o read() primitive encoding aware.
+ o wide-character aware cursor movements.
+ o unicode description table, inline character-value.
+ o libiconv() dll relative paths.
+ o 32-bit internal key-codes.
+ o Alt+Keycode handler (win32 - experimental).
+
+ * utf8 filenames.
+
Mon Apr 12 20:50:30 2021 adamy
+ * BUILD 17 release
+
* duktape 2.6.0
Sat Apr 3 11:50:35 2021 adamy
diff --git a/INSTALL b/INSTALL
index cd5060a4..7cfea496 100644
--- a/INSTALL
+++ b/INSTALL
@@ -129,12 +129,34 @@
On UNIX variations (including cygwin), build by following these steps:
- a. (optional) set the CFLAGS environment variable according to
- your preference. If you are using a GNU compiler, then -O or -O2 (there is
- little advantage in using -O2 and it usually builds larger executables) is fine.
+ a. Optionally the following external packages can be in additional
+ functionality; auto-detected during 'conf
+
+ enchant-devel Wrapper library for various s
+ hunspell-devel Spell checker and morphologic
+ aspell-devel GNU aspell.
+
+ enca-devel Extremely Naive Charset Analy
+ libguess-devel Speed character set detection
+
+ libexplain-devel System message add-value.
+
+ libarchive-devel Archive access.
+ libicu-devel Character conversion.
+
+ libbz2-devel bzip compression.
+ libzstd-devel gz compression.
+ xz-devel liblzma.
+ snappy-devel google fast/compressor/decomp
+
+ plus the following, which are generally available.
+
+ ncurses-devel Terminal interface library.
+ libcurl-devel Network tools.
+ openssl-devel OpenSSL.
b. If you're building with a non-standard compiler or one known, by something
- other than "cc" or "gcc" then you can set the environment variable "CC" to that.
+ other than "cc" or "gcc" then you can set the environment variable "CC" to that.
c. Run the `configure' script by typing:
@@ -142,15 +164,15 @@
Alternatively select one the available preset configurations
- ./configure_withmost
- ./configure_withcurses
- ./configure_withncurses
- ./configure_withncursesw
- ./configure_withtermcap
- ./configure_withtermlib
- ./configure_withtinfo
+ ./support/configure_withmost
+ ./support/configure_withcurses
+ ./support/configure_withncurses
+ ./support/configure_withncursesw
+ ./support/configure_withtermcap
+ ./support/configure_withtermlib
+ ./support/configure_withtinfo
- d. Note any errors. Please get back to me at the address below if you have any
+ d. Note any errors. Please get back to me via github below if you have any
configure problems.
e. This should built the entire set of makefiles and one include file in
@@ -160,7 +182,8 @@
f. Build the entire tree with:
- make
+ make
+ or make release
g. Note that the default installation paths (compiled into GRIEF, but may be
overridden with environment variables or command line) are:
@@ -278,5 +301,5 @@ setting up terminal features.
*Some* of this information may be obsolete, but most of it will be fine.
-$Id: INSTALL,v 1.14 2020/04/22 22:59:18 cvsuser Exp $
+$Id: INSTALL,v 1.15 2021/06/10 06:13:01 cvsuser Exp $
diff --git a/Makefile.in b/Makefile.in
index b980a671..244aba42 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,8 +1,8 @@
# -*- mode: mak; -*-
-# $Id: Makefile.in,v 1.47 2020/06/18 20:35:15 cvsuser Exp $
+# $Id: Makefile.in,v 1.52 2022/03/22 10:50:24 cvsuser Exp $
# GRIEF - top level makefile.
#
-# Copyright (c) 1998 - 2020, Adam Young.
+# Copyright (c) 1998 - 2022, Adam Young.
# All rights reserved.
#
# This file is part of the GRIEF Editor.
@@ -36,7 +36,7 @@ PKG_TARNAME = @PACKAGE_TARNAME@
PKG_URL = @PACKAGE_URL@
PKG_VERSION = @PACKAGE_VERSION@
ifeq ("","$(PKG_VERSION)")
-PKG_VERSION = 3.2.1
+PKG_VERSION = 3.2.2
endif
PKG_VERSION_1 =$(word 1,$(subst ., ,$(PKG_VERSION)))
PKG_VERSION_2 =$(word 2,$(subst ., ,$(PKG_VERSION)))
@@ -105,18 +105,63 @@ E=
A= .a
O= .o
LP= lib
+E= .exe
CLEAN= *.bak *~ *.BAK *.swp *.tmp core *.core a.out
-XCLEAN=
+XCLEAN= $(D_BIN)/*.map
# Configuration
+ifneq "" "$(filter win32,@build_os@)"
+BUSYBOX= @BUSYBOX@
+ifeq ($(BUSYBOX),busybox)
+BUSYBOX= $(shell which busybox 2>/dev/null)
+endif
+ECHO= $(BUSYBOX) echo
+else
+ECHO= echo
+endif
+
ifeq ("$(BUILD_TYPE)","") #default
-BUILD_TYPE= debug
-MAKEFLAGS+= BUILD_TYPE=debug
+
+.PHONY: help clean vclean build package
+help clean vclean build package:
+ifneq ("$(word 1,$(MAKECMDGOALS))","debug")
+ifneq ("$(word 1,$(MAKECMDGOALS))","release")
+ @$(ECHO) -n -e "\
+ |\n\
+ | make [release or debug] target \n\
+ |\n\
+ | Build one or more of the following targets recursively within each sub-directory. \n\
+ |\n\
+ | Targets: \n\
+ |\n\
+ | build - build everything. \n\
+ | package - build package. \n\
+ | clean - delete everything which can be remade. \n\
+ | vclean - delete all. \n\
+ | help - command line usage. \n\
+ "
endif
-ifneq ("$(BUILD_TYPE)","release")
+endif
+ @echo .
+
+.PHONY: release
+release:
+ $(MAKE) BUILD_TYPE=release $(filter-out release, $(MAKECMDGOALS))
+
+.PHONY: debug
+debug:
+ $(MAKE) BUILD_TYPE=debug $(filter-out debug, $(MAKECMDGOALS))
+
+else # BUILD_TYPE
+
+ifeq ("$(BUILD_TYPE)","debug")
RTSUFFIX=d
+else
+ifneq ("$(BUILD_TYPE)","release")
+$(error invalid BUILD_TYPE; debug or release expected)
+endif
endif
# Directories
@@ -140,6 +185,7 @@ D_HLPDOC= $(ROOT)/hlpdoc
BUILDNUMBER= BUILDNUMBER.in
BUILDINFO= include/edbuildinfo.h
+PACKAGEINFO= include/edpackageinfo.h
# Compilers, programs
@@ -167,10 +213,6 @@ INNO= "C:/Program Files (x86)/Inno Setup 5/Compil32"
endif
endif
-BUSYBOX= @BUSYBOX@
-ifeq ($(BUSYBOX),busybox)
-BUSYBOX= $(shell which busybox 2>/dev/null)
-endif
# Common flags
@@ -233,7 +275,10 @@ BINS=\
$(D_BIN)/grcpp$(E) \
$(D_BIN)/grmandoc$(E) \
$(D_BIN)/grunch$(E)
-
+ifneq "" "$(filter mingw32 win32,@build_os@)"
+BINS+= $(D_BIN)/grwc$(E)
+endif
+
LIBS=
ifneq "" "$(filter mingw32 win32,@build_os@)"
LIBS+= $(LW)win32
@@ -248,6 +293,7 @@ LIBS+=\
$(LW)onigrx \
$(LW)tre \
$(LW)chartable \
+ $(LW)widechar \
$(LW)charudet \
$(LW)vfs \
$(LW)duktape \
@@ -264,13 +310,32 @@ DIRECTORIES=\
#########################################################################################
# Rules
-.PHONY: build release debug directories install
-build: directories buildinfo libs bins import
+.PHONY: build directories install
+build: directories artifacts libs bins import
$(MAKE) -C $(D_HLPDOC)
$(MAKE) -C $(D_MACSRC)
+.PHONY: help
+help:
+ @$(ECHO) -e "\
+ |\n\
+ | make [release or debug] target \n\
+ |\n\
+ | Build one or more of the following targets recursively within each sub-directory. \n\
+ |\n\
+ | Targets: \n\
+ |\n\
+ | build - build everything. \n\
+ | package - build all packages. \n\
+ | clean - delete everything which can be remade. \n\
+ | help - command line usage. \n\
+ "
+
+.PHONY: release
release:
$(MAKE) BUILD_TYPE=release $(filter-out release, $(MAKECMDGOALS))
+
+.PHONY: debug
debug:
$(MAKE) BUILD_TYPE=debug $(filter-out debug, $(MAKECMDGOALS))
@@ -284,14 +349,12 @@ endif
directories: $(DIRECTORIES)
+artifacts: buildinfo
+
%/.created:
-@$(PERL) ./win32/mkdir_p.pl $(@D)
@echo "++ do not delete, grief edit managed content ++" > $@
-.PHONY: package
-package: import
- $(INNO) ./win32/gr-inno-setup.iss
-
.PHONY: import
import: $(IMPORT)
@@ -314,19 +377,49 @@ $(D_BIN)/$(PLBRNAME).dll: $(LIBPLBRPATH)
@$(CP) -f $(subst /,\,$^) $@
endif
+.PHONY: package
+package: import packageinfo
+ $(INNO) ./win32/gr-inno-setup.iss
+ -$(RM) $(PACKAGEINFO)
#########################################################################################
# Applications
-buildinfo: $(BUILDINFO)
+BUILD_DATE= $(shell date +'%Y%m%d')
+ifneq ($(APPVEYOR_BUILD_NUMBER),)
+BUILD_NUMBER= $(APPVEYOR_BUILD_NUMBER)
+else ifneq ($(GITHUB_RUN_NUMBER),)
+BUILD_NUMBER= $(GITHUB_RUN_NUMBER)
+else
+BUILD_NUMBER= $(shell cat ./$(BUILDNUMBER))
+endif
-PKG_BUILD_DATE= $(shell date +'%Y%m%d')
-PKG_BUILD_NUMBER= $(shell cat ./$(BUILDNUMBER))
+.PHONY: buildinfo
+$(BUILDINFO): Makefile $(BUILDNUMBER) buildinfo
+buildinfo:
+ @echo updating buildinfo.h ...
+ -@$(PERL) ./buildinfo.pl -o $(BUILDINFO) --prefix="GR_" --package="$(PACKAGE)" --name="$(PKG_NAME)" --version="$(PKG_VERSION)" \
+ --date="$(BUILD_DATE)" --build="$(BUILD_NUMBER)" --toolchain="@TOOLCHAINEXT@" --type="$(BUILD_TYPE)" \
+ --bindir="$(BINDIR)" --sbindir="$(SBINDIR)" --libexecdir="$(LIBEXECDIR)" --libdir="$(LIBDIR)" --datadir="$(DATADIR)"
+
+.PHONY: packageinfo
+packageinfo:
+ -@$(PERL) ./buildinfo.pl -o $(PACKAGEINFO) --prefix="GR_" --package="$(PACKAGE)" --name="$(PKG_NAME)" --version="$(PKG_VERSION)" \
+ --date="$(BUILD_DATE)" --build="$(BUILD_NUMBER)" --toolchain="@TOOLCHAINEXT@" --type="$(BUILD_TYPE)"
+
+buildinfo.h: BUILDNUMBER buildinfo.pl
+
+ifneq ($(APPVEYOR_BUILD_NUMBER),)
+BUILDNUMBER:
+ @echo importing appveyor build number ...
+ @echo $(APPVEYOR_BUILD_NUMBER)>$@
+endif
-$(BUILDINFO): Makefile $(BUILDNUMBER)
- -@$(PERL) ./buildinfo.pl -o $@ --prefix="GR_" --package="$(PACKAGE)" --name="$(PKG_NAME)" --version="$(PKG_VERSION)" \
- --date="$(PKG_BUILD_DATE)" --build="$(PKG_BUILD_NUMBER)" --toolchain="@TOOLCHAINEXT@" --type="$(BUILD_TYPE)" \
- --bindir="$(BINDIR)" --sbindir="$(SBINDIR)" --libexecdir="$(LIBEXECDIR)" --libdir="$(LIBDIR)" --datadir="$(DATADIR)"
+ifneq ($(GITHUB_RUN_NUMBER),)
+BUILDNUMBER:
+ @echo importing github build number ...
+ @echo $(GITHUB_RUN_NUMBER)>$@
+endif
.PHONY: new_buildnumber
new_buildnumber:
@@ -358,7 +451,9 @@ $(D_BIN)/grmandoc$(E): $(D_BIN)/.created libs
$(D_BIN)/grunch$(E): $(D_BIN)/.created libs
$(MAKE) -C $(D_GRUNCH)
-
+
+$(D_BIN)/grwc$(E): $(D_BIN)/.created libs
+ $(MAKE) -C util
#########################################################################################
# Rules
@@ -412,6 +507,7 @@ endif
$(MAKE) -C libonigrx clean
$(MAKE) -C libtre clean
$(MAKE) -C libchartable clean
+ $(MAKE) -C libwidechar clean
$(MAKE) -C libcharudet clean
$(MAKE) -C libvfs clean
$(MAKE) -C libduktape clean
@@ -448,6 +544,7 @@ distclean: clean
libonigrx/Makefile \
libtre/Makefile \
libchartable/Makefile \
+ libwidechar/Makefile \
libcharudet/Makefile \
libvfs/Makefile \
libduktape/Makefile \
@@ -465,3 +562,5 @@ distclean: clean
# endif
#end
+
+endif # BUILD_TYPE
diff --git a/auto/configure b/auto/configure
index ab462a35..56a8b928 100755
--- a/auto/configure
+++ b/auto/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 1.72 .
+# From configure.in Revision: 1.75 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for GRIEF 3.2.1.
#
@@ -788,7 +788,6 @@ infodir
docdir
oldincludedir
includedir
-runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -938,7 +937,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1191,15 +1189,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
- -runstatedir | --runstatedir | --runstatedi | --runstated \
- | --runstate | --runstat | --runsta | --runst | --runs \
- | --run | --ru | --r)
- ac_prev=runstatedir ;;
- -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
- | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
- | --run=* | --ru=* | --r=*)
- runstatedir=$ac_optarg ;;
-
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1337,7 +1326,7 @@ fi
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 runstatedir
+ libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1490,7 +1479,6 @@ Fine tuning of the installation directories:
--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]
- --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -17235,7 +17223,7 @@ EOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC __attribute__ directives..." >&5
$as_echo "$as_me: checking for $CC __attribute__ directives..." >&6;}
cat > conftest.$ac_ext <.
+# ==end==
#
use strict;
@@ -104,6 +126,7 @@
#define ${prefix}VERSION_1 ${version1}
#define ${prefix}VERSION_2 ${version2}
#define ${prefix}VERSION_3 ${version3}
+#define ${prefix}VERSION_4 ${buildnumber}
#define ${prefix}BUILD_DATE "${builddate}"
#define ${prefix}BUILD_NUMBER "${buildnumber}"
EOT
@@ -114,10 +137,10 @@
if ($buildtype) {
print FILE "#define BUILD_TYPE \"${buildtype}\"\n";
- die "makeconfig.pm: build type verb 'release' or 'debug' expected.\n"
+ die "buildinfo.pm: build type verb 'release' or 'debug' expected.\n"
if ($buildtype !~ /release/ && $buildtype !~ /debug/);
-
- die "makeconfig.pm: build type verbs 'release' and 'debug' are mutually exclusive.\n"
+
+ die "buildinfo.pm: build type verbs 'release' and 'debug' are mutually exclusive.\n"
if ($buildtype =~ /release/ && $buildtype =~ /debug/);
print FILE "#define BUILD_TYPE_RELEASE 1\n"
@@ -176,4 +199,3 @@
#end
-
diff --git a/contrib/.cvsignore b/contrib/.cvsignore
index f3c7a7c5..8d2c87c4 100644
--- a/contrib/.cvsignore
+++ b/contrib/.cvsignore
@@ -1 +1,4 @@
Makefile
+*.err
+include
+
diff --git a/contrib/extags/.cvsignore b/contrib/extags/.cvsignore
new file mode 100644
index 00000000..8a4ee951
--- /dev/null
+++ b/contrib/extags/.cvsignore
@@ -0,0 +1,4 @@
+Makefile
+*.err
+.unpacked.*
+
diff --git a/contrib/flex/.cvsignore b/contrib/flex/.cvsignore
index 91db0003..934c7f94 100644
--- a/contrib/flex/.cvsignore
+++ b/contrib/flex/.cvsignore
@@ -2,3 +2,9 @@ flex-2.5.10
.unpacked.*
Makefile
*.err
+parse.c
+parse.h
+scan.c
+skel.c
+
+
diff --git a/contrib/flex/.gitignore b/contrib/flex/.gitignore
index f7986f77..3a903dbb 100644
--- a/contrib/flex/.gitignore
+++ b/contrib/flex/.gitignore
@@ -2,3 +2,9 @@ file-2.510/
.unpacked.*
Makefile
*.err
+parse.c
+parse.h
+scan.c
+skel.c
+
+
diff --git a/contrib/hunspell/.cvsignore b/contrib/hunspell/.cvsignore
new file mode 100644
index 00000000..ae9b9137
--- /dev/null
+++ b/contrib/hunspell/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+*.err
+.unpacked.*
diff --git a/contrib/libarchive/.cvsignore b/contrib/libarchive/.cvsignore
new file mode 100644
index 00000000..8a4ee951
--- /dev/null
+++ b/contrib/libarchive/.cvsignore
@@ -0,0 +1,4 @@
+Makefile
+*.err
+.unpacked.*
+
diff --git a/contrib/libbzip2/.cvsignore b/contrib/libbzip2/.cvsignore
new file mode 100644
index 00000000..8a4ee951
--- /dev/null
+++ b/contrib/libbzip2/.cvsignore
@@ -0,0 +1,4 @@
+Makefile
+*.err
+.unpacked.*
+
diff --git a/contrib/libcitrus/.cvsignore b/contrib/libcitrus/.cvsignore
new file mode 100644
index 00000000..8c40b219
--- /dev/null
+++ b/contrib/libcitrus/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.err
diff --git a/contrib/libcitrus/libpaths.c b/contrib/libcitrus/libpaths.c
index 81a67a7e..662f9a5e 100644
--- a/contrib/libcitrus/libpaths.c
+++ b/contrib/libcitrus/libpaths.c
@@ -1,8 +1,8 @@
-/* $Id: libpaths.c,v 1.8 2015/03/01 02:56:37 cvsuser Exp $
+/* $Id: libpaths.c,v 1.10 2021/06/14 14:12:57 cvsuser Exp $
*
* libcitrus implementation
*
- * Copyright (c) 2012-2015 Adam Young.
+ * Copyright (c) 2012-2021 Adam Young.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -53,6 +53,7 @@ static const char * x_application_dir = APPLICATIONDIR;
static const char * getpath(const char *application, const char *dir, char *buffer, const int buflen);
static int getexedir(char *buf, int maxlen);
+static int getdlldir(char *buf, int maxlen);
static void dospath(char *path);
@@ -197,8 +198,8 @@ getpath(const char *application, const char *dir, char *buffer, const int buflen
{
int len, done = FALSE;
- // , generally same as INSTALLDIR
- if ((len = getexedir(buffer, buflen)) > 0) {
+ // , generally same as INSTALLDIR
+ if ((len = getdlldir(buffer, buflen)) > 0) {
_snprintf(buffer + len, buflen - len, "/%s", dir);
buffer[buflen - 1] = 0;
if (0 == _access(buffer, 0)) {
@@ -206,6 +207,17 @@ getpath(const char *application, const char *dir, char *buffer, const int buflen
}
}
+ // , generally same as INSTALLDIR
+ if (! done) {
+ if ((len = getexedir(buffer, buflen)) > 0) {
+ _snprintf(buffer + len, buflen - len, "/%s", dir);
+ buffer[buflen - 1] = 0;
+ if (0 == _access(buffer, 0)) {
+ done = TRUE;
+ }
+ }
+ }
+
//
if (! done) {
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROGRAM_FILES, NULL, 0, buffer))) {
@@ -256,11 +268,11 @@ getpath(const char *application, const char *dir, char *buffer, const int buflen
static int
getexedir(char *buf, int maxlen)
{
- if (GetModuleFileName(NULL, buf, maxlen)) {
+ if (GetModuleFileNameA(NULL, buf, maxlen)) {
const int len = strlen(buf);
char *cp;
- for (cp = buf + len; (cp > buf) && (*cp != '\\'); cp--)
+ for (cp = buf + len; (cp > buf) && (*cp != '\\'); --cp)
/*cont*/;
if ('\\' == *cp) {
cp[1] = '\0'; // remove program
@@ -272,6 +284,35 @@ getexedir(char *buf, int maxlen)
}
+static int
+getdlldir(char *buf, int maxlen)
+{
+#if defined(__WATCOMC__)
+ HMODULE hm = NULL;
+
+ if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
+ GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR) &__citrus_PATH_ICONV, &hm) != 0 &&
+ GetModuleFileNameA(hm, buf, maxlen)) {
+#else
+ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
+
+ if (GetModuleFileNameA((HINSTANCE)&__ImageBase, buf, maxlen)) {
+#endif
+ const int len = strlen(buf);
+ char *cp;
+
+ for (cp = buf + len; (cp > buf) && (*cp != '\\'); --cp)
+ /*cont*/;
+ if ('\\' == *cp) {
+ cp[1] = '\0'; // remove library
+ return (cp - buf) + 1;
+ }
+ return len;
+ }
+ return -1;
+}
+
+
static void
dospath(char *path)
{
@@ -290,3 +331,4 @@ dospath(char *path)
}
*path = 0;
}
+
diff --git a/contrib/libcitrus/src/citrus_csmapper.c b/contrib/libcitrus/src/citrus_csmapper.c
index 8cb52f2d..53ec8b2e 100644
--- a/contrib/libcitrus/src/citrus_csmapper.c
+++ b/contrib/libcitrus/src/citrus_csmapper.c
@@ -316,7 +316,7 @@ open_serial_mapper(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict * __restrict rcm,
const char *src, const char *pivot, const char *dst)
{
- char buf[PATH_MAX];
+ char buf[4 * PATH_MAX];
snprintf(buf, sizeof(buf), "%s/%s,%s/%s", src, pivot, pivot, dst);
diff --git a/contrib/libcitrus/src/citrus_csmapper.h b/contrib/libcitrus/src/citrus_csmapper.h
index 31b06e40..dbf25b08 100644
--- a/contrib/libcitrus/src/citrus_csmapper.h
+++ b/contrib/libcitrus/src/citrus_csmapper.h
@@ -27,7 +27,7 @@
*/
#ifndef _CITRUS_CSMAPPER_H_
-#define _CITRUS_CSMAPPER_H
+#define _CITRUS_CSMAPPER_H_
#define _citrus_csmapper _citrus_mapper
#define _citrus_csmapper_close _citrus_mapper_close
diff --git a/contrib/libcitrus/src/citrus_ctype_template.h b/contrib/libcitrus/src/citrus_ctype_template.h
index 4bb1b629..c27a3791 100644
--- a/contrib/libcitrus/src/citrus_ctype_template.h
+++ b/contrib/libcitrus/src/citrus_ctype_template.h
@@ -238,8 +238,8 @@ _FUNCNAME(mbsrtowcs_priv)(_ENCODING_INFO * __restrict ei,
_DIAGASSERT(nresult != 0);
_DIAGASSERT(ei != NULL);
_DIAGASSERT(psenc != NULL);
- _DIAGASSERT(s == NULL);
- _DIAGASSERT(*s == NULL);
+ _DIAGASSERT(s != NULL);
+ _DIAGASSERT(*s != NULL);
/* if pwcs is NULL, ignore n */
if (pwcs == NULL)
diff --git a/contrib/libguess/.cvsignore b/contrib/libguess/.cvsignore
new file mode 100644
index 00000000..8c40b219
--- /dev/null
+++ b/contrib/libguess/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.err
diff --git a/contrib/libiconv/.cvsignore b/contrib/libiconv/.cvsignore
new file mode 100644
index 00000000..8c40b219
--- /dev/null
+++ b/contrib/libiconv/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.err
diff --git a/contrib/libiconv/iconv.h b/contrib/libiconv/iconv.h
index e3bbd313..52a395c6 100644
--- a/contrib/libiconv/iconv.h
+++ b/contrib/libiconv/iconv.h
@@ -1,10 +1,10 @@
#ifndef ICONV_H_INCLUDED
#define ICONV_H_INCLUDED
-/* $Id: iconv.h,v 1.5 2020/06/18 19:52:45 cvsuser Exp $
+/* $Id: iconv.h,v 1.6 2021/06/13 16:32:03 cvsuser Exp $
*
* win32 - libiconv
*
- * Copyright (c) 2012-2015 Adam Young.
+ * Copyright (c) 2012-2021 Adam Young.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -62,7 +62,7 @@ LIBICONV_LINKAGE int LIBICONV_ENTRY iconv_close(iconv_t cd);
LIBICONV_LINKAGE int LIBICONV_ENTRY iconv_errno(void);
LIBICONV_LINKAGE size_t LIBICONV_ENTRY __iconv(iconv_t handle, const char **in, size_t *szin, char **out,
- size_t *szout, unsigned flags, size_t *invalids);
+ size_t *szout, unsigned flags, size_t *invalids);
LIBICONV_LINKAGE int LIBICONV_ENTRY __iconv_get_list(char ***rlist, size_t *rsz);
@@ -74,6 +74,10 @@ LIBICONV_LINKAGE const char *LIBICONV_ENTRY __iconv_PATH_CSMAPPER(void);
LIBICONV_LINKAGE const char *LIBICONV_ENTRY __iconv_PATH_ICONV(void);
+#if !defined(__ICONV_F_HIDE_INVALID)
+#define __ICONV_F_HIDE_INVALID 0x0001
+#endif
+
__END_DECLS
#endif /*ICONV_H_INCLUDED*/
diff --git a/contrib/libiconv/iconv1.txt b/contrib/libiconv/iconv1.txt
new file mode 100644
index 00000000..86465eb7
--- /dev/null
+++ b/contrib/libiconv/iconv1.txt
@@ -0,0 +1,150 @@
+ICONV(3) NetBSD Library Functions Manual ICONV(3)
+
+NAME
+
+ iconv_open, iconv_close, iconv -- codeset conversion functions
+
+
+LIBRARY
+
+ Standard C Library (libc, -lc)
+
+
+SYNOPSIS
+
+ #include
+
+ iconv_t
+ iconv_open(const char *dstname, const char *srcname);
+
+ int
+ iconv_close(iconv_t cd);
+
+ size_t
+ iconv(iconv_t cd, char ** restrict src, size_t * restrict srcleft,
+ char ** restrict dst, size_t * restrict dstleft);
+
+
+DESCRIPTION
+
+ The iconv_open() function opens a converter from the codeset srcname to
+ the codeset dstname and returns its descriptor.
+
+ The iconv_close() function closes the specified converter cd.
+
+ The iconv() function converts the string in the buffer *src of length
+ *srcleft bytes and stores the converted string in the buffer *dst of size
+ *dstleft bytes. After calling iconv(), the values pointed to by src,
+ srcleft, dst, and dstleft are updated as follows:
+
+ *src Pointer to the byte just after the last character
+ fetched.
+
+ *srcleft Number of remaining bytes in the source buffer.
+
+ *dst Pointer to the byte just after the last character stored.
+
+ *dstleft Number of remainder bytes in the destination buffer.
+
+ If the string pointed to by *src contains a byte sequence which is not a
+ valid character in the source codeset, the conversion stops just after
+ the last successful conversion. If the output buffer is too small to
+ store the converted character, the conversion also stops in the same way.
+ In these cases, the values pointed to by src, srcleft, dst, and dstleft
+ are updated to the state just after the last successful conversion.
+
+ If the string pointed to by *src contains a character which is valid
+ under the source codeset but can not be converted to the destination
+ codeset, the character is replaced by an ``invalid character'' which
+ depends on the destination codeset, e.g., `?', and the conversion is con-
+ tinued. iconv() returns the number of such ``invalid conversions''.
+
+ If src or *src is NULL and the source and/or destination codesets are
+ stateful, iconv() places these into their initial state.
+
+ 1. If both dst and *dst are non-NULL, iconv() stores the shift
+ sequence for the destination switching to the initial state in
+ the buffer pointed to by *dst. The buffer size is specified
+ by the value pointed to by dstleft as above. iconv() will
+ fail if the buffer is too small to store the shift sequence.
+
+ 2. On the other hand, dst or *dst may be NULL. In this case, the
+ shift sequence for the destination switching to the initial
+ state is discarded.
+
+
+RETURN VALUES
+
+ Upon successful completion of iconv_open(), it returns a conversion
+ descriptor. Otherwise, iconv_open() returns (iconv_t)-1 and sets errno
+ to indicate the error.
+
+ Upon successful completion of iconv_close(), it returns 0. Otherwise,
+ iconv_close() returns -1 and sets errno to indicate the error.
+
+ Upon successful completion of iconv(), it returns the number of
+ ``invalid'' conversions. Otherwise, iconv() returns (size_t)-1 and sets
+ errno to indicate the error.
+
+
+ERRORS
+
+ The iconv_open() function may cause an error in the following cases:
+
+ [EINVAL] There is no converter specified by srcname and
+ dstname.
+
+ [ENOMEM] Memory is exhausted.
+
+ The iconv_close() function may cause an error in the following case:
+
+ [EBADF] The conversion descriptor specified by cd is invalid.
+
+ The iconv() function may cause an error in the following cases:
+
+ [E2BIG] The output buffer pointed to by *dst is too small to
+ store the result string.
+
+ [EBADF] The conversion descriptor specified by cd is invalid.
+
+ [EILSEQ] The string pointed to by *src contains a byte sequence
+ which does not describe a valid character of the
+ source codeset.
+
+ [EINVAL] The string pointed to by *src terminates with an
+ incomplete character or shift sequence.
+
+
+SEE ALSO
+
+ iconv(1)
+
+
+STANDARDS
+
+ iconv_open(), iconv_close(), and iconv() conform to IEEE Std 1003.1-2001
+ (``POSIX.1'').
+
+ Historically, the definition of iconv has not been consistent across
+ operating systems. This is due to an unfortunate historical mistake,
+ documented in this e-mail:
+
+ https://www5.opengroup.org/sophocles2/show_mail.tpl?&source=L&listname=austin-group-l&id=7404.
+
+ The standards page for the header file defined the second argu-
+ ment of iconv() as char **, but the standards page for the iconv() imple-
+ mentation defined it as const char **. The standards committee later
+ chose to change the function definition to follow the header file defini-
+ tion (without const), even though the version with const is arguably more
+ correct. NetBSD used initially the const form. It was decided to reject
+ the committee's regression and become (technically) incompatible.
+
+ This decision was changed in NetBSD 10 and the iconv() prototype was syn-
+ chronized with the standard.
+
+
+BUGS
+
+ If iconv() is aborted due to the occurrence of some error, the ``invalid
+ conversion'' count mentioned above is unfortunately lost.
+
diff --git a/contrib/libiconv/libiconv.c b/contrib/libiconv/libiconv.c
index 3fef29e1..b0426fd3 100644
--- a/contrib/libiconv/libiconv.c
+++ b/contrib/libiconv/libiconv.c
@@ -1,4 +1,4 @@
-/* $Id: libiconv.c,v 1.3 2012/09/03 23:10:15 ayoung Exp $
+/* $Id: libiconv.c,v 1.4 2021/06/13 16:33:45 cvsuser Exp $
*
* Copyright (c)2003 Citrus Project,
* All rights reserved.
@@ -62,6 +62,16 @@ iconv_open(const char *out, const char *in)
{
int ret;
struct _citrus_iconv *handle;
+ char *s;
+
+ // gnu-iconv compat, remove //IGNORE, //TRANSLIT and other options
+ if (NULL != (s = strchr(out, '/'))) {
+ const size_t outlen = s - out;
+ char *t_out = alloca(outlen + 1);
+
+ memcpy(t_out, out, outlen), t_out[outlen] = 0;
+ out = t_out;
+ }
ret = _citrus_iconv_open(&handle, _PATH_ICONV, in, out);
if (ret) {
@@ -89,7 +99,7 @@ iconv_close(iconv_t handle)
LIBICONV_LINKAGE size_t LIBICONV_ENTRY
iconv(iconv_t handle, const char **__restrict in, size_t *__restrict szin,
- char ** __restrict out, size_t * __restrict szout)
+ char ** __restrict out, size_t * __restrict szout)
{
int err;
size_t ret;
@@ -120,7 +130,7 @@ iconv_errno(void)
LIBICONV_LINKAGE size_t LIBICONV_ENTRY
__iconv(iconv_t handle, const char **in, size_t *szin, char **out,
- size_t *szout, unsigned flags, size_t *invalids)
+ size_t *szout, unsigned flags, size_t *invalids)
{
int err;
size_t ret;
diff --git a/contrib/libiconv/makelib.def b/contrib/libiconv/makelib.def
index 1d6d9c28..16904324 100644
--- a/contrib/libiconv/makelib.def
+++ b/contrib/libiconv/makelib.def
@@ -1,10 +1,10 @@
-# $Id: makelib.def,v 1.3 2012/09/21 17:32:53 ayoung Exp $
+# $Id: makelib.def,v 1.4 2021/06/12 15:34:33 cvsuser Exp $
# win32 makelib configuration
#
inc=../include
lbl=LIBICONV
lib=libiconv.lib
def=HAVE_LIBICONV
-def=HAVE_ICONVL_H
-def=HAVE_LIBICONVL_DLL="libiconv.1.0.dll"
+def=HAVE_ICONV_CITRUS_H
+def=HAVE_LIBICONV_CITRUS_DLL="libiconv.1.0.dll"
diff --git a/contrib/libintl/.cvsignore b/contrib/libintl/.cvsignore
new file mode 100644
index 00000000..8c40b219
--- /dev/null
+++ b/contrib/libintl/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.err
diff --git a/contrib/liblzma/.cvsignore b/contrib/liblzma/.cvsignore
index e171ef07..8a4ee951 100644
--- a/contrib/liblzma/.cvsignore
+++ b/contrib/liblzma/.cvsignore
@@ -1 +1,4 @@
-xz-5.2.*/
+Makefile
+*.err
+.unpacked.*
+
diff --git a/contrib/liblzma/Makefile.in b/contrib/liblzma/Makefile.in
index 09464fc7..3ffd04e1 100644
--- a/contrib/liblzma/Makefile.in
+++ b/contrib/liblzma/Makefile.in
@@ -1,5 +1,5 @@
# -*- mode: mak; indent-tabs-mode: t; tab-width: 8 -*-
-# $Id: Makefile.in,v 1.8 2020/06/18 20:35:16 cvsuser Exp $
+# $Id: Makefile.in,v 1.9 2022/03/22 04:10:50 cvsuser Exp $
# liblzma makefile and grxz
#
#
@@ -234,6 +234,8 @@ TSKS= $(LZMAUTIL)
LZMA=no
ifeq ("@TOOLCHAIN@","owc20")
else ifeq ("@TOOLCHAIN@","owc19")
+else ifeq ("@TOOLCHAIN@","vs170")
+LZMA=yes
else ifeq ("@TOOLCHAIN@","vs160")
LZMA=yes
else ifeq ("@TOOLCHAIN@","vs150")
diff --git a/contrib/libmagic/.cvsignore b/contrib/libmagic/.cvsignore
new file mode 100644
index 00000000..8c6968cf
--- /dev/null
+++ b/contrib/libmagic/.cvsignore
@@ -0,0 +1,6 @@
+Makefile
+*.err
+.unpacked.*
+magic
+magic.mgc
+
diff --git a/contrib/libmagic/.gitignore b/contrib/libmagic/.gitignore
index bfdcbd35..8ca4f0e8 100644
--- a/contrib/libmagic/.gitignore
+++ b/contrib/libmagic/.gitignore
@@ -1,4 +1,5 @@
file-511/
file-5.29/
+.unpacked.*
magic
-magic.mgc
\ No newline at end of file
+magic.mgc
diff --git a/contrib/libmagic/config.h b/contrib/libmagic/config.h
index a29f7409..3ec815d3 100644
--- a/contrib/libmagic/config.h
+++ b/contrib/libmagic/config.h
@@ -103,6 +103,7 @@
/* Define to 1 if you have the `getline' function. */
//#define HAVE_GETLINE
+#undef HAVE_GETLINE
/* Define to 1 if you have the header file. */
#define HAVE_GETOPT_H
@@ -132,28 +133,26 @@
/* Define to 1 if you have the header file. */
#if !defined(HAVE_LIMITS_H) && (defined(_MSC_VER) || defined(__WATCOMC__))
-#define HAVE_LIMITS_H
+#define HAVE_LIMITS_H 1
#endif
/* Define to 1 if you have the header file. */
-#if defined(__WATCOMC__)
-#undef HAVE_LOCALE_H
-#endif
+ //#undef HAVE_LOCALE_H
/* Define to 1 if you have the `localtime_r' function. */
//#undef HAVE_LOCALTIME_R
/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
#if !defined(HAVE_MBRTOWC) && (defined(_MSC_VER) || defined(__WATCOMC__))
-#define HAVE_MBRTOWC
+#define HAVE_MBRTOWC 1
#endif
/* Define to 1 if declares mbstate_t. */
-#define HAVE_MBSTATE_T
+#define HAVE_MBSTATE_T 1
/* Define to 1 if you have the header file. */
#if !defined(HAVE_MEMORY_H) && (defined(_MSC_VER) || defined(__WATCOMC__))
-#define HAVE_MEMORY_H
+#define HAVE_MEMORY_H 1
#endif
/* Define to 1 if you have the `mkostemp' function. */
@@ -183,16 +182,16 @@
//#undef HAVE_SIG_T
/* Define to 1 if you have the header file. */
-#define HAVE_STDDEF_H
+#define HAVE_STDDEF_H 1
/* Define to 1 if you have the header file. */
#if !defined(HAVE_STDINT_H) && (defined(_MSC_VER) || defined(__WATCOMC__))
-#define HAVE_STDINT_H
+#define HAVE_STDINT_H 1
#endif
/* Define to 1 if you have the header file. */
#if !defined(HAVE_STDLIB_H) && (defined(_MSC_VER) || defined(__WATCOMC__))
-#define HAVE_STDLIB_H
+#define HAVE_STDLIB_H 1
#endif
/* Define to 1 if you have the `strcasestr' function. */
@@ -200,7 +199,7 @@
/* Define to 1 if you have the `strerror' function. */
#if !defined(HAVE_STRERROR) && (defined(_MSC_VER) || defined(__WATCOMC__))
-#define HAVE_STRERROR
+#define HAVE_STRERROR 1
#endif
/* Define to 1 if you have the header file. */
@@ -208,7 +207,7 @@
/* Define to 1 if you have the header file. */
#if !defined(HAVE_STRING_H) && (defined(_MSC_VER) || defined(__WATCOMC__))
-#define HAVE_STRING_H
+#define HAVE_STRING_H 1
#endif
/* Define to 1 if you have the `strlcat' function. */
@@ -227,7 +226,7 @@
//#define HAVE_STRTOUL
/* HAVE_STRUCT_OPTION */
-#define HAVE_STRUCT_OPTION
+#define HAVE_STRUCT_OPTION 1
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
//#undef HAVE_STRUCT_STAT_ST_RDEV
@@ -275,7 +274,7 @@
/* Define to 1 if you have the header file. */
#if !defined(HAVE_UNISTD_H) && (defined(_MSC_VER) || defined(__WATCOMC__))
-#define HAVE_UNISTD_H
+#define HAVE_UNISTD_H 1
#endif
/* Define to 1 if you have the `uselocale' function. */
diff --git a/contrib/libregex/.cvsignore b/contrib/libregex/.cvsignore
new file mode 100644
index 00000000..8c40b219
--- /dev/null
+++ b/contrib/libregex/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.err
diff --git a/contrib/libz/.cvsignore b/contrib/libz/.cvsignore
new file mode 100644
index 00000000..8a4ee951
--- /dev/null
+++ b/contrib/libz/.cvsignore
@@ -0,0 +1,4 @@
+Makefile
+*.err
+.unpacked.*
+
diff --git a/contrib/libz/.gitignore b/contrib/libz/.gitignore
index d9cd289c..350c24e0 100644
--- a/contrib/libz/.gitignore
+++ b/contrib/libz/.gitignore
@@ -1 +1 @@
-zlib-1.2.*/
\ No newline at end of file
+zlib-1.2.*/
diff --git a/contrib/makedepend/.cvsignore b/contrib/makedepend/.cvsignore
new file mode 100644
index 00000000..8c40b219
--- /dev/null
+++ b/contrib/makedepend/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.err
diff --git a/contrib/makedepend/Makefile.in b/contrib/makedepend/Makefile.in
index 96308936..c410bb4a 100644
--- a/contrib/makedepend/Makefile.in
+++ b/contrib/makedepend/Makefile.in
@@ -1,5 +1,5 @@
# -*- mode: mak; indent-tabs-mode: t; tab-width: 8 -*-
-# $Id: Makefile.in,v 1.8 2020/06/18 20:35:16 cvsuser Exp $
+# $Id: Makefile.in,v 1.9 2022/03/21 17:12:44 cvsuser Exp $
# makedepend makefile
#
#
@@ -45,6 +45,7 @@ D_BIN= $(ROOT)/bin@TOOLCHAINEXT@/$(BUILD_TYPE)
D_OBJ= $(ROOT)/objects@TOOLCHAINEXT@/$(BUILD_TYPE)/makedepend
D_LIB= $(ROOT)/lib@TOOLCHAINEXT@/$(BUILD_TYPE)
+
# Common flags
XFLAGS=
@@ -79,12 +80,13 @@ RMDFLAGS= -rf
#########################################################################################
# Targets
-MKDEPENDUTIL= $(D_BIN)/makedepend$(E)
-
MKDEPENDSRC= ./makedepend-1.0.5
VPATH= $(MKDEPENDSRC)
-UTILOBJS=\
+BINS=\
+ $(D_BIN)/makedepend$(E)
+
+MAKEDEPENDOBJS=\
$(D_OBJ)/main$(O) \
$(D_OBJ)/cppsetup$(O) \
$(D_OBJ)/ifparser$(O) \
@@ -92,24 +94,27 @@ UTILOBJS=\
$(D_OBJ)/parse$(O) \
$(D_OBJ)/pr$(O)
-OBJS= $(UTILOBJS)
-TSKS= $(MKDEPENDUTIL)
+OBJS= $(MAKEDEPENDOBJS)
+
#########################################################################################
# Rules
.PHONY: build release debug
-build: object $(TSKS)
+build: object $(BINS)
release:
$(MAKE) BUILD_TYPE=release $(filter-out release, $(MAKECMDGOALS))
+
debug:
$(MAKE) BUILD_TYPE=debug $(filter-out debug, $(MAKECMDGOALS))
.PHONY: object
object: $(D_OBJ)/.created
-$(MKDEPENDUTIL): $(UTILOBJS)
- $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)
+
+$(D_BIN)/makedepend$(E): MAPFILE=$(basename $@).map
+$(D_BIN)/makedepend$(E): $(MAKEDEPENDOBJS)
+ $(CC) $(LDFLAGS) -o $@ $(MAKEDEPENDOBJS) $(LDLIBS) @LDMAPFILE@
%/.created:
-@mkdir $(@D)
@@ -124,4 +129,3 @@ $(D_OBJ)/%$(O): %.c
#end
-
diff --git a/gm/.cvsignore b/gm/.cvsignore
new file mode 100644
index 00000000..8c40b219
--- /dev/null
+++ b/gm/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.err
diff --git a/gm/Makefile.in b/gm/Makefile.in
index 8f8047a5..ff4f8994 100644
--- a/gm/Makefile.in
+++ b/gm/Makefile.in
@@ -1,9 +1,9 @@
# -*- mode: mak; indent-tabs-mode: t; tab-width: 8 -*-
-# $Id: Makefile.in,v 1.22 2020/06/18 20:35:16 cvsuser Exp $
+# $Id: Makefile.in,v 1.23 2022/03/22 08:04:52 cvsuser Exp $
# GRIEF Macro Compiler makefile.
#
#
-# Copyright (c) 1998 - 2020, Adam Young.
+# Copyright (c) 1998 - 2022, Adam Young.
# All rights reserved.
#
# This file is part of the GRIEF Editor.
@@ -44,6 +44,8 @@ XCLEAN=
CC= @CC@
RM= @RM@
+PERL= @PERL@
+LIBTOOL= @LIBTOOL@
# Configuration
@@ -84,7 +86,7 @@ else
CFLAGS+= $(CDEBUG) $(CWARN) $(CINCLUDE) $(CEXTRA) $(XFLAGS)
LDFLAGS= $(LDDEBUG) @LDFLAGS@
endif
-LDLIBS= -L$(D_LIB) @LIBS@ -lsplay -lmisc -lllist -lmisc @LIBMALLOC@ @EXTRALIBS@
+LDLIBS= -L$(D_LIB) @LDLIBS@ -lsplay -lllist -lmisc @LIBS@ @LIBYACC@ @LIBM@ @LIBMALLOC@ @EXTRALIBS@
YFLAGS= -d
ARFLAGS= rcv
@@ -117,7 +119,7 @@ debug:
$(D_BIN)/$(TARGET): MAPFILE=$(basename $@).map
$(D_BIN)/$(TARGET): $(D_OBJ)/.created $(OBJS)
- $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) @LDMAPFILE@
+ $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) @LDMAPFILE@
$(D_OBJ)/.created:
-@mkdir $(D_OBJ)
diff --git a/gr/Makefile.in b/gr/Makefile.in
index 29fee939..1bd0324e 100644
--- a/gr/Makefile.in
+++ b/gr/Makefile.in
@@ -1,5 +1,5 @@
# -*- mode: mak; indent-tabs-mode: t; tab-width: 8 -*-
-# $Id: Makefile.in,v 1.79 2021/04/18 16:16:57 cvsuser Exp $
+# $Id: Makefile.in,v 1.80 2021/07/05 15:01:26 cvsuser Exp $
# GRIEF editor makefile.
#
#
@@ -190,7 +190,7 @@ LDFLAGS+= -rdynamic
endif
endif
-LDLIBS= -L$(D_LIB) -lbsddb -lbsdfetch -lbsdio -lchartable -lvfs -lsplay -lllist -lmisc -lonigrx -ltre
+LDLIBS= -L$(D_LIB) -lbsddb -lbsdfetch -lbsdio -lwidechar -lchartable -lvfs -lsplay -lllist -lmisc -lonigrx -ltre
LDLIBS+= @LDLIBS@ @LIBS@
LDLIBS+= @LIBENCA@ @LIBSPELL@ @LIBICU@ @LIBICONV@ @LIBCURL@ @LIBOPENSSL@ @LIBARCHIVE@ @LIBMAGIC@
LDLIBS+= @LIBM@ @EXTRALIBS@
diff --git a/gr/anchor.c b/gr/anchor.c
index e4d5ea4d..c4606126 100644
--- a/gr/anchor.c
+++ b/gr/anchor.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_anchor_c,"$Id: anchor.c,v 1.45 2020/04/21 00:01:54 cvsuser Exp $")
+__CIDENT_RCSID(gr_anchor_c,"$Id: anchor.c,v 1.46 2021/06/10 06:13:01 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: anchor.c,v 1.45 2020/04/21 00:01:54 cvsuser Exp $
+/* $Id: anchor.c,v 1.46 2021/06/10 06:13:01 cvsuser Exp $
* Anchor primitives.
*
*
@@ -638,7 +638,7 @@ do_raise_anchor(void) /* int () */
inq_marked, raise_anchor, drop_anchor
*/
void
-do_mark(void) /* int ([int type = NULL]) */
+do_mark(void) /* int ([int type = NULL]) */
{
if (curbp) {
@@ -787,13 +787,13 @@ greatest_line(LINENO start_line, LINENO end_line)
}
while (line <= end_line) {
- const LINE_t *lp = linep(line);
-
+ const LINE_t *lp = vm_lock_line(line);
if (lp) {
const int col = line_column2(lp, line, (int) llength(lp));
if (col > maxcol) {
maxcol = col;
}
+ vm_unlock(line);
}
++line;
}
@@ -874,4 +874,5 @@ do_swap_anchor(void) /* int () */
acc_assign_int(ret);
}
-/*end*/
\ No newline at end of file
+/*end*/
+
diff --git a/gr/basic.c b/gr/basic.c
index 330353fb..b12c13ec 100644
--- a/gr/basic.c
+++ b/gr/basic.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_basic_c,"$Id: basic.c,v 1.29 2015/02/11 23:25:12 cvsuser Exp $")
+__CIDENT_RCSID(gr_basic_c,"$Id: basic.c,v 1.31 2021/10/18 13:14:57 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: basic.c,v 1.29 2015/02/11 23:25:12 cvsuser Exp $
+/* $Id: basic.c,v 1.31 2021/10/18 13:14:57 cvsuser Exp $
* Basic cursor movement.
*
*
@@ -800,11 +800,9 @@ do_move_abs(void) /* int ([int line = -1], [int col = -1], [int bu
if (bp && bp != curbp) {
BUFFER_t *ocurbp = curbp;
- curbp = bp;
- set_hooked();
+ set_curbp(bp);
move2((LINENO) line, (LINENO) col, (clip ? MOVE_CLIP : 0));
- curbp = ocurbp;
- set_hooked();
+ set_curbp(ocurbp);
return;
}
}
@@ -889,12 +887,13 @@ move_next_char(int n, int flags_notused)
*/
LINENO dot = 0, count = 0;
- lp = vm_lock_line(line);
- dot = (col > 1 ? line_offset2(lp, line, col, LOFFSET_NORMAL) : 0);
- if (dot < (LINENO)llength(lp)) {
- count = line_sizeregion(lp, col, dot, n, NULL, &col);
+ if (NULL != (lp = vm_lock_line2(line))) {
+ dot = (col > 1 ? line_offset_const(lp, line, col, LOFFSET_NORMAL) : 0);
+ if (dot < (LINENO)llength(lp)) {
+ count = line_sizeregion(lp, col, dot, n, NULL, &col);
+ }
+ vm_unlock(line);
}
- vm_unlock(line);
if ((n -= count) <= 0) {
goto done;
}
@@ -909,28 +908,28 @@ done:; trace_ilog("\tdone (line:%d, col:%d)\n", (int)line, (int)col);
* binary/8bit
*/
const int nl = (BFTST(curbp, BF_BINARY) ? 0 : 1);
- int offset, length;
- LINE_t *lp;
+ int dot, length;
+ const LINE_t *lp;
while (n > 0 && line < bottomline) {
- lp = vm_lock_line(line);
- offset = (col > 1 ? line_offset2(lp, line, col, LOFFSET_NORMAL) : 0);
- length = llength(lp);
-
- if (offset + n <= length) { /* EOL, move to next line */
- if (offset + n == length) {
- vm_unlock(line);
- ++line;
- col = 1;
- } else { /* otherwise, position within current line */
- col = line_column2(lp, line, offset + n);
- vm_unlock(line);
+ if (NULL != (lp = vm_lock_line2(line))) {
+ dot = (col > 1 ? line_offset_const(lp, line, col, LOFFSET_NORMAL) : 0);
+ length = llength(lp);
+
+ if ((dot + n) <= length) { /* EOL, move to next line */
+ if ((dot + n) == length) {
+ vm_unlock(line);
+ ++line;
+ col = 1;
+ } else { /* otherwise, position within current line */
+ col = line_column2(lp, line, dot + n);
+ vm_unlock(line);
+ }
+ break; /* done */
}
- break; /* done */
+ n -= (length - dot) + nl; /* remove line, plus optional nl */
+ vm_unlock(line);
}
- n -= (length - offset) + nl; /* remove line, plus optional nl */
-
- vm_unlock(line);
++line, col = 1;
}
}
@@ -958,13 +957,13 @@ move_prev_char(int n)
*/
const LINECHAR *cp, *start, *end;
int count, column;
- LINE_t *lp;
while (n > 0 && line >= 1) { /* MCHAR */
/*
* setup line references
*/
- lp = vm_lock_line(line);
+ const LINE_t *lp = vm_lock_line(line);
+
cp = start = ltext(lp);
end = start + llength(lp);
ED_TRACE_LINE2(lp)
@@ -1056,7 +1055,7 @@ done:; trace_ilog("==> line:%d, col:%d\n", line, col);
line = 1; /* top of buffer */
break;
}
- dot = llength(linep(line)); /* EOL */
+ dot = llength(linep0(line)); /* EOL */
n -= nl;
}
}
@@ -1130,25 +1129,75 @@ mov_gotoline(int n)
static void
-mov_char(const int n, const int direction)
+mov_char(const int cnt, const int direction)
{
const LINENO cline = *cur_line, ccol = *cur_col;
int ncol;
- assert(n > 0);
+ assert(cnt > 0);
assert(0 == direction || 1 == direction);
if (direction) { /* right */
- if ((ncol = ccol + n) < ccol) {
+ if ((ccol + cnt) >= LINEMAX) {
ncol = LINEMAX;
+
+ } else {
+ ncol = ccol + cnt;
+
+ if (! BFTST(curbp, BF_BINARY)) { /* MCHAR */
+ const LINE_t *lp = vm_lock_line2(cline);
+ if (lp) { /* TODO: LI_MBSWIDE */
+ int pos = 1, width, length;
+ const LINECHAR *cp = ltext(lp),
+ *end = cp + llength(lp);
+ int32_t ch = 0;
+
+ while (pos < ncol && cp < end) {
+ width = character_decode(pos, cp, end, &length, &ch, NULL);
+ if ((pos + width) > ncol) {
+ assert(width > 1);
+ ncol = pos + width; /* align to next wide-character */
+ break;
+ }
+ pos += width;
+ cp += length;
+ }
+ vm_unlock(cline);
+ }
+ }
}
+
} else { /* left */
- if (n >= ccol) {
+ if (cnt >= ccol) {
ncol = 1;
+
} else {
- ncol = ccol - n;
+ ncol = ccol - cnt;
+
+ if (! BFTST(curbp, BF_BINARY)) { /* MCHAR */
+ const LINE_t *lp = vm_lock_line2(cline);
+ if (lp) { /* TODO: LI_MBSWIDE */
+ int pos = 1, width, length;
+ const LINECHAR *cp = ltext(lp),
+ *end = cp + llength(lp);
+ int32_t ch = 0;
+
+ while (pos < ncol && cp < end) {
+ width = character_decode(pos, cp, end, &length, &ch, NULL);
+ if ((pos + width) > ncol) {
+ assert(width > 1);
+ ncol = pos; /* align to prev wide-character */
+ break;
+ }
+ pos += width;
+ cp += length;
+ }
+ vm_unlock(cline);
+ }
+ }
}
}
+
move(cline, ncol, MOVE_OBEY);
}
@@ -1157,11 +1206,12 @@ static void
mov_line(const int n, const int direction)
{
const LINENO cline = *cur_line, ccol = *cur_col;
- int nline;
+ int nline, ncol = ccol;
assert(n > 0);
assert(0 == direction || 1 == direction);
+ /* reposition line */
if (direction) { /* down */
if ((nline = cline + n) < cline) {
nline = LINEMAX;
@@ -1173,7 +1223,31 @@ mov_line(const int n, const int direction)
nline = cline - n;
}
}
- move(nline, ccol, MOVE_OBEY);
+
+ /* realign column, if within a wide-character */
+ if (! BFTST(curbp, BF_BINARY)) { /* MCHAR */
+ const LINE_t *lp = vm_lock_line2(nline);
+ if (lp) { /* TODO: LI_MBSWIDE */
+ int pos = 1, width, length;
+ const LINECHAR *cp = ltext(lp),
+ *end = cp + llength(lp);
+ int32_t ch = 0;
+
+ while (pos < ccol && cp < end) {
+ width = character_decode(pos, cp, end, &length, &ch, NULL);
+ if ((pos + width) > ccol) {
+ assert(width > 1);
+ ncol = pos; /* align wide-character */
+ break;
+ }
+ pos += width;
+ cp += length;
+ }
+ vm_unlock(nline);
+ }
+ }
+
+ move(nline, ncol, MOVE_OBEY);
}
@@ -1294,4 +1368,5 @@ move(LINENO nline, LINENO ncol, int flags)
trace_ilog("\t= [line:%d, col:%d] : %d\n", (int)nline, (int)ncol, ret);
return ret;
}
+
/*end*/
diff --git a/gr/buffer.c b/gr/buffer.c
index 0fb7373e..7aa07873 100644
--- a/gr/buffer.c
+++ b/gr/buffer.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_buffer_c,"$Id: buffer.c,v 1.48 2020/04/21 00:01:55 cvsuser Exp $")
+__CIDENT_RCSID(gr_buffer_c,"$Id: buffer.c,v 1.50 2021/10/18 13:16:15 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: buffer.c,v 1.48 2020/04/21 00:01:55 cvsuser Exp $
+/* $Id: buffer.c,v 1.50 2021/10/18 13:16:15 cvsuser Exp $
* Buffer managment.
*
*
@@ -309,9 +309,9 @@ buf_anycb(void)
for (bp = buf_first(); bp; bp = buf_next(bp)) {
if (buf_isdirty(bp)) {
if (BFTST(bp, BF_AUTOWRITE)) { /* unconditonal write */
- curbp = bp;
+ set_curbp(bp);
if (file_write(NULL, 0 /*TODO - WRITE_NOTRIGGER*/) < 0) {
- curbp = saved_curbp;
+ set_curbp(saved_curbp);
return TRUE;
}
} else {
@@ -319,7 +319,7 @@ buf_anycb(void)
}
}
}
- curbp = saved_curbp;
+ set_curbp(saved_curbp);
if (0 == mods) {
return FALSE;
@@ -350,15 +350,15 @@ buf_anycb(void)
for (bp = buf_first(); bp; bp = buf_next(bp)) {
if (buf_isdirty(bp)) {
- curbp = bp;
+ set_curbp(bp);
if (file_write(NULL, 0 /*XXX - WRITE_NOTRIGGER*/) < 0) {
- curbp = saved_curbp;
+ set_curbp(saved_curbp);
return TRUE;
}
}
}
- curbp = saved_curbp;
+ set_curbp(saved_curbp);
return FALSE;
}
@@ -746,7 +746,7 @@ buf_kill(int bufnum)
}
}
if (NULL == curbp) {
- curbp = buf_first();
+ curbp = buf_first();
}
assert(curbp != bp);
set_hooked();
@@ -943,8 +943,7 @@ buf_line_length(const BUFFER_t *bp, /*__CBOOL*/ int marked)
woldline = curwp->w_old_line;
}
- curbp = (BUFFER_t *)bp;
- set_hooked();
+ set_curbp((BUFFER_t *)bp);
if (! marked || FALSE == anchor_get(NULL, NULL, &a)) {
a.start_line = 1;
a.end_line = curbp->b_numlines; /* NEWLINE */
@@ -952,7 +951,7 @@ buf_line_length(const BUFFER_t *bp, /*__CBOOL*/ int marked)
for (line = a.start_line; line <= a.end_line; ++line) {
if ((col = line_column_eol(line)) > maxcol) {
- maxlinep = vm_lock_line(line);
+ maxlinep = vm_lock_line2(line);
maxcol = col;
}
}
@@ -962,8 +961,7 @@ buf_line_length(const BUFFER_t *bp, /*__CBOOL*/ int marked)
curbp->b_maxlength = maxcol;
}
- curbp = saved_curbp;
- set_hooked();
+ set_curbp(saved_curbp);
/* Make sure buffer is repositioned where it was. */
if (curwp) {
@@ -990,9 +988,7 @@ buf_change_window(WINDOW_t *wp)
set_buffer_parms(curbp, curwp);
curwp->w_status |= WFHARD;
wp->w_status |= WFHARD;
- curwp = wp;
- curbp = curwp->w_bufp;
- set_hooked();
+ set_curwpbp(wp, wp->w_bufp);
}
diff --git a/gr/builtin.c b/gr/builtin.c
index 778f4843..037d1232 100644
--- a/gr/builtin.c
+++ b/gr/builtin.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_builtin_c,"$Id: builtin.c,v 1.59 2020/06/03 14:12:36 cvsuser Exp $")
+__CIDENT_RCSID(gr_builtin_c,"$Id: builtin.c,v 1.63 2021/10/18 13:21:23 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: builtin.c,v 1.59 2020/06/03 14:12:36 cvsuser Exp $
+/* $Id: builtin.c,v 1.63 2021/10/18 13:21:23 cvsuser Exp $
* Builtin expresssion evaluation.
*
*
@@ -60,7 +60,7 @@ static void execute_builtin(const BUILTIN *bp, const LIST *lp);
static void __CINLINE arg_error(const BUILTIN *bp, enum ARGERRORS msg, struct SAVED *saved_str, struct SAVED *ssp, int arg);
static void __CINLINE arg_free(struct SAVED *saved_str, struct SAVED *ssp);
-static int arg_expand(const BUILTIN *bp, int varargs, int largc,
+static int arg_expand(const BUILTIN *bp, int varargs, int largc,
LISTV **largv, LISTV **lap, struct SAVED **lsaved, struct SAVED **ssp);
static int execute_expr2(const argtype_t arg, const LIST *argp, LISTV *lap);
@@ -108,7 +108,7 @@ iscsym(int c) /*TODO: compat_iscsym()*/
/*
* execute_str ---
- * Take a string, possiblity entered via the the command prompt, taking the
+ * Take a string, possiblity entered via the the command prompt, taking the
* form , parse and then execute the specified macro.
*
* Arguments can be either int, float otherwise treated as a string.
@@ -526,7 +526,7 @@ execute_xmacro(register const LIST *lp, const LIST *lp_argv)
++mptr->m_hits;
#endif
- if (bp) bp->b_macro = mptr; /* pop chain */
+ if (bp) bp->b_macro = mptr; /* pop chain */
mptr->m_ftime = FALSE; /* first time */
x_msglevel = omsglevel; /* restore message level */
@@ -648,7 +648,7 @@ execute_builtin(const BUILTIN *bp, const LIST *lp)
case F_NULL:
break;
case EEXECUTE: /* ... */
- goto execute;
+ goto execute;
case EERROR:
/*
* One last chance --
@@ -676,7 +676,7 @@ execute_builtin(const BUILTIN *bp, const LIST *lp)
}
/*
- * Move onto the next argument descriptor.
+ * Move onto the next argument descriptor.
* Note: Don't move if an indefinite list and last descriptor; as it repeats.
*/
if (! varargs || argtypes[1] /*not-last*/) {
@@ -738,7 +738,7 @@ execute_builtin(const BUILTIN *bp, const LIST *lp)
} else {
assert(0 == argtype && 0 == *argtypes);
- assert(op == *lp);
+ assert((NULL == lp && op == F_HALT) || op == *lp);
if (F_HALT != op) { /* unexpected argments */
arg_error(bp, ERR_TOOMANY, lsaved, ssp, 0);
@@ -866,12 +866,12 @@ arg_expand(const BUILTIN *bp, int varargs, int largc, LISTV **largv, LISTV **lap
const size_t lapi = (size_t)(*lap - *largv);
const size_t sspi = (size_t)(*ssp - *lsaved);
- struct SAVED *nlsaved = NULL;
+ struct SAVED *nlsaved = NULL;
LISTV *nlargv;
int nvarargs;
/*
- * Varargs available ?
+ * Varargs available ?
*/
assert(varargs >= -1);
if (! varargs) {
@@ -956,8 +956,8 @@ static const int state_tbl[][12] = {
/*ls-i*/ {-1, -1, F_INT, -1, F_STR, F_LIT, F_LIST, -1, -1, F_RSTR, F_RLIST, -1 },
/*lsf-*/ {-1, -1, -1, F_FLOAT, F_STR, F_LIT, F_LIST, -1, -1, F_RSTR, F_RLIST, -1 },
/*lsfi*/ {-1, -1, F_INT, F_FLOAT, F_STR, F_LIT, F_LIST, -1, F_NULL, F_RSTR, F_RLIST, -1 },
- };
-
+ };
+
static const int state2_tbl[][11] = {
/*
* Symbol type conversions.
@@ -1081,6 +1081,31 @@ check_hooked(void)
#endif //!NDEBUG
+void
+set_curbp(BUFFER_t *bp)
+{
+ curbp = bp;
+ set_hooked();
+}
+
+
+void
+set_curwp(WINDOW_t *wp)
+{
+ curwp = wp;
+ set_hooked();
+}
+
+
+void
+set_curwpbp(WINDOW_t *wp, BUFFER_t *bp)
+{
+ curwp = wp;
+ curbp = bp;
+ set_hooked();
+}
+
+
void
set_hooked(void)
{
@@ -1114,7 +1139,7 @@ set_hooked(void)
if (curbp != currentbp) {
trace_ilog("set_hooked(line:%d,col:%d,num:%d,fname:\"%s\")\n", \
- *cur_line, *cur_col, (curbp ? curbp->b_bufnum : -1), (curbp ? curbp->b_fname : ""));
+ *cur_line, *cur_col, (curbp ? curbp->b_bufnum : -1), (curbp ? c_string(curbp->b_fname) : ""));
currentbp = curbp;
}
diff --git a/gr/builtin.h b/gr/builtin.h
index 415aa516..8df17588 100644
--- a/gr/builtin.h
+++ b/gr/builtin.h
@@ -1,11 +1,11 @@
#ifndef GR_BUILTIN_H_INCLUDED
#define GR_BUILTIN_H_INCLUDED
#include
-__CIDENT_RCSID(gr_builtin_h,"$Id: builtin.h,v 1.25 2020/04/21 00:01:55 cvsuser Exp $")
+__CIDENT_RCSID(gr_builtin_h,"$Id: builtin.h,v 1.26 2021/10/18 13:20:42 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: builtin.h,v 1.25 2020/04/21 00:01:55 cvsuser Exp $
+/* $Id: builtin.h,v 1.26 2021/10/18 13:20:42 cvsuser Exp $
* Builtin primitive table.
*
*
@@ -34,6 +34,7 @@ extern void execute_event_ctrlc(void);
extern void execute_event_usr1(void);
extern void execute_event_usr2(void);
extern const char * execute_name(void);
+
extern void set_hooked(void);
extern LINENO *cur_line, *cur_col;
@@ -77,4 +78,4 @@ extern void *x_returns;
__CEND_DECLS
-#endif /*GR_BUILTIN_H_INCLUDED*/
\ No newline at end of file
+#endif /*GR_BUILTIN_H_INCLUDED*/
diff --git a/gr/cmain.c b/gr/cmain.c
index 2c33bc99..3942dbb7 100644
--- a/gr/cmain.c
+++ b/gr/cmain.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_cmain_c,"$Id: cmain.c,v 1.36 2020/05/03 21:09:41 cvsuser Exp $")
+__CIDENT_RCSID(gr_cmain_c,"$Id: cmain.c,v 1.41 2021/10/24 16:46:45 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: cmain.c,v 1.36 2020/05/03 21:09:41 cvsuser Exp $
+/* $Id: cmain.c,v 1.41 2021/10/24 16:46:45 cvsuser Exp $
* Main body, startup and command-line processing.
*
*
@@ -145,6 +145,9 @@ static struct argoption options[] = {
{ "encoding", arg_required, NULL, 317, "Default file encoding",
"" },
+ { "ucsver", arg_required, NULL, 320, "Unicode version; wcwidth support",
+ "" },
+
{ "nograph", arg_none, NULL, 5, "Disable use of graphic characters" },
{ "nounicode", arg_none, NULL, 307, "Disable use of UNICODE graphic characters" },
@@ -327,6 +330,8 @@ int x_bftype_default = BFTYP_UNDEFINED;
/* Default file encoding. */
const char * x_encoding_default = NULL;
+const char * x_unicode_version = NULL;
+
uint32_t xf_test = 0; /* BITMAP enables test code --- internal use only --- */
int x_mflag = FALSE; /* TRUE whilst processing -m strings to avoid messages. */
@@ -354,12 +359,14 @@ static const char * m_strings[MAX_M+1]; /* Array of pointer to -m string
BUFFER_t * curbp = NULL; /* Current buffer. */
WINDOW_t * curwp = NULL; /* Current window. */
-static void path_cat(const char *path, const char *sub, char *buf);
+static int path_cat(const char *path, const char *sub, char *buf);
static char * path_cook(const char *name);
static void argv_init(int *argcp, char **argv);
static int argv_process(int doerr, int argc, const char **argv);
+static void unicode_init(void);
+
static void env_setup(void);
static __CINLINE int env_iswhite(const char ch);
static int env_define(const char *cp);
@@ -450,12 +457,16 @@ cmain(int argc, char **argv)
// textdomain(PACKAGE);
#endif
#endif
-#if defined(_MSC_VER)
+#if defined(HAVE__TZSET)
_tzset();
#else
tzset(); /* localtime requirement */
#endif
+#if defined(_WIN32)
+ w32_utf8filenames_enable();
+#endif
+
if (argc < 0) cpp_linkage("");
x_umask = (mode_t)fileio_umask(0); /* our umask */
@@ -475,6 +486,7 @@ cmain(int argc, char **argv)
search_init(); /* regular expression engine */
mchar_info_init();
mchar_guess_init();
+ mchar_iconv_init();
playback_init();
bookmark_init();
position_init();
@@ -508,6 +520,7 @@ cmain(int argc, char **argv)
if (xf_spell) {
spell_init();
}
+ unicode_init();
vtready();
if (xf_mouse) {
if (mouse_init("")) { /* mouse interface */
@@ -572,8 +585,8 @@ cmain(int argc, char **argv)
firstbp = curbp;
}
}
- buf_show(curbp = firstbp, curwp);
- set_hooked();
+ buf_show(firstbp, curwp);
+ set_curbp(firstbp);
} else { /* load default quietly */
const char *grfile = ggetenv("GRFILE");
@@ -635,7 +648,7 @@ panic(const char *fmt, ...)
}
-static void
+static int
path_cat(const char *path, const char *sub, char *buf)
{
char t_path[1024] = {0}, t_realpath[1024] = {0};
@@ -650,10 +663,13 @@ path_cat(const char *path, const char *sub, char *buf)
}
if (NULL == sub ||
- 0 == fileio_access(path, 0)) { /* push if it exists */
+ 0 == sys_access(path, 0)) { /* push if it exists */
strcat(buf, path);
strcat(buf, sys_pathdelimiter());
+ return 1;
}
+
+ return 0;
}
@@ -1268,6 +1284,10 @@ argv_process(int doerr, int argc, const char **argv)
x_encoding_default = args.val;
break;
+ case 320: /* --ucsver= */
+ x_unicode_version = args.val;
+ break;
+
case 308: /* --term= */
gputenv2("TERM", args.val);
break;
@@ -1280,7 +1300,7 @@ argv_process(int doerr, int argc, const char **argv)
gputenv2("GRHELP", args.val);
break;
- case 319: /* --grprofile= */
+ case 319: /* --grprofile= */
gputenv2("GRPROFILE", args.val);
break;
@@ -1338,6 +1358,16 @@ argv_process(int doerr, int argc, const char **argv)
}
+static void
+unicode_init(void)
+{
+ if (NULL == x_unicode_version)
+ x_unicode_version = ggetenv("UNICODE_VERSION");
+ if (x_unicode_version)
+ ucs_width_set(x_unicode_version);
+}
+
+
static void
env_setup(void)
{
@@ -1368,7 +1398,9 @@ env_setup(void)
sprintf(buf, "GRPATH=");
if (binpath[0]) { /* rel to binary image */
- path_cat(binpath, "../macros", buf);
+ if (0 == path_cat(binpath, "../macros", buf)) {
+ path_cat(binpath, "../../macros", buf);
+ }
#if defined(__MINGW32__)
path_cat(binpath, "../lib/grief/macros", buf);
#endif
@@ -1388,7 +1420,9 @@ env_setup(void)
sprintf(buf, "GRHELP=");
if (binpath[0]) { /* rel to binary image */
- path_cat(binpath, "../help", buf);
+ if (0 == path_cat(binpath, "../help", buf)) {
+ path_cat(binpath, "../../help", buf);
+ }
#if defined(__MINGW32__)
path_cat(binpath, "../lib/grief/help", buf);
#endif
@@ -1641,7 +1675,6 @@ editor_setup(void)
}
k_init(bp);
- curbp = bp; /* current ones. */
bp->b_nwnd = 1; /* displayed. */
bp->b_keyboard = NULL;
@@ -1654,17 +1687,13 @@ editor_setup(void)
wp->w_type = W_TILED;
wp->w_tab = 0; /* TABLINE */
window_append(wp);
- curwp = wp;
-
- cur_line = &bp->b_line;
- cur_col = &bp->b_col;
wp->w_w = (uint16_t)(ttcols() - 2); /* 0..78 */
wp->w_h = (uint16_t)(ttrows() - 3);
wp->w_status = WFHARD;
window_title(wp, "*scratch*", "");
- set_hooked();
+ set_curwpbp(wp, bp);
}
@@ -1778,4 +1807,4 @@ usage(int what)
#undef HINDENT
}
-/*end*/
\ No newline at end of file
+/*end*/
diff --git a/gr/cmap.c b/gr/cmap.c
index 1bef71c3..0f0001f0 100644
--- a/gr/cmap.c
+++ b/gr/cmap.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_cmap_c,"$Id: cmap.c,v 1.32 2021/04/14 14:09:54 cvsuser Exp $")
+__CIDENT_RCSID(gr_cmap_c,"$Id: cmap.c,v 1.34 2021/07/18 23:03:18 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: cmap.c,v 1.32 2021/04/14 14:09:54 cvsuser Exp $
+/* $Id: cmap.c,v 1.34 2021/07/18 23:03:18 cvsuser Exp $
* Character map management/primitives.
*
*
@@ -260,7 +260,7 @@ cmap_build(cmap_t *cmap)
cmapchr_str(mc, (const char *)(cp - 2));
}
/* printable non-ascii/C1 characters */
- } else if (isutf8 || (is8bit && i < 0xff)) {
+ } else if (isutf8 || (is8bit && i <= 0xff)) {
*cp++ = (unsigned char)i;
*cp++ = 0;
cmapchr_str(mc, (const char *)(cp - 2));
@@ -1250,4 +1250,5 @@ do_set_char_map(void) /* int (int mapid|string name, list definition)
}
}
#endif
+
/*eof*/
diff --git a/gr/debug.c b/gr/debug.c
index 5b13fce1..b1a6e2e6 100644
--- a/gr/debug.c
+++ b/gr/debug.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_debug_c,"$Id: debug.c,v 1.35 2020/04/21 00:01:55 cvsuser Exp $")
+__CIDENT_RCSID(gr_debug_c,"$Id: debug.c,v 1.36 2021/07/04 08:39:16 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: debug.c,v 1.35 2020/04/21 00:01:55 cvsuser Exp $
+/* $Id: debug.c,v 1.36 2021/07/04 08:39:16 cvsuser Exp $
* internal debug/diagnositics.
*
*
@@ -230,7 +230,7 @@ trace_lines(void)
for (bp = buf_first(); bp; bp = buf_next((BUFFER_t *)bp)) {
register const LINE_t *lp;
- trace_log("Buffer %s:\n", bp->b_fname);
+ trace_log("Buffer %s:\n", c_string(bp->b_fname));
TAILQ_FOREACH(lp, &bp->b_lineq, l_node) {
sxprintf(buf, sizeof(buf), "\tLine %3u: old=%u, used=%2d, size=%2d, fl=0x%x, chunk=%p\n",
(unsigned)++lineno, (unsigned)lp->l_oldlineno, (int)lp->l_used, (int)lp->l_size,
@@ -459,7 +459,7 @@ trace_refs(void)
const BUILTIN *bp, *endbp = builtin + builtin_count;
for (bp = builtin; bp < endbp; ++bp) {
- trace_log("%5u %5u %s\n", bp->b_reference, bp->b_replacement, bp->b_name);
+ trace_log("%5u %5u %s\n", bp->b_reference, bp->b_replacement, c_string(bp->b_name));
#if defined(DO_PROFILE)
#endif
}
@@ -606,4 +606,4 @@ trace_string(const char *str)
trace_log("\"");
}
-/*end*/
\ No newline at end of file
+/*end*/
diff --git a/gr/dialog.c b/gr/dialog.c
index 252d54aa..2b8031f4 100644
--- a/gr/dialog.c
+++ b/gr/dialog.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_dialog_c,"$Id: dialog.c,v 1.29 2019/01/26 22:27:08 cvsuser Exp $")
+__CIDENT_RCSID(gr_dialog_c,"$Id: dialog.c,v 1.30 2021/07/18 23:03:18 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: dialog.c,v 1.29 2019/01/26 22:27:08 cvsuser Exp $
+/* $Id: dialog.c,v 1.30 2021/07/18 23:03:18 cvsuser Exp $
* Dialog manager.
*
*
@@ -237,7 +237,7 @@ dialog_shutdown(void)
*<>
Macro: dialog_create - Build a dialog resource.
- int
+ int
dialog_create(list decl)
Macro Description:
@@ -296,7 +296,7 @@ dialog_shutdown(void)
! DLGA_TOOLTIP String Tooltip topic.
! DLGA_X Int Horizontal position.
- ! DLGA_Y Int Vertical position.
+ ! DLGA_Y Int Vertical position.
! DLGA_COLS Int Width in columns.
! DLGA_ROWS Int Height in rows.
@@ -328,14 +328,14 @@ dialog_shutdown(void)
! DLGA_TEXT_ONLY n/a
! DLGA_GUI_ONLY n/a
! DLGA_ACCELERATOR String
- ! DLGA_HOTKEY Integer
+ ! DLGA_HOTKEY Integer
! DLGA_GREYED n/a
! DLGA_ACTIVE n/a
- ! DLGA_SENSITIVE Integer
- ! DLGA_PADX Integer
- ! DLGA_PADY Integer
+ ! DLGA_SENSITIVE Integer
+ ! DLGA_PADX Integer
+ ! DLGA_PADY Integer
- ! DLGA_ORIENTATION Integer
+ ! DLGA_ORIENTATION Integer
! DLGA_HIDDEN n/a
! DLGA_VISIBLE n/a
! DLGA_KEYDOWN Boolean
@@ -345,9 +345,9 @@ dialog_shutdown(void)
! DLCA_USERDATA Int
! DLGA_EDEDITABLE Boolean
- ! DLGA_EDMAXLENGTH Integer
+ ! DLGA_EDMAXLENGTH Integer
! DLGA_EDVISIBLITY Boolean
- ! DLGA_EDPOSITION Integer
+ ! DLGA_EDPOSITION Integer
! DLGA_EDPLACEHOLDER String
! DLGA_LBCOUNT Integer
@@ -358,20 +358,20 @@ dialog_shutdown(void)
! DLGA_LBDUPLICATES Integer
! DLGA_LBCLEAR n/a
- ! DLGA_LBCURSOR Integer
- ! DLGA_LBACTIVE Integer
- ! DLGA_LBDISPLAYTEXT Integer
- ! DLGA_LBDISPLAYTEXTLEN Integer
- ! DLGA_LBTEXT Integer
- ! DLGA_LBTEXTLEN Integer
+ ! DLGA_LBCURSOR Integer
+ ! DLGA_LBACTIVE Integer
+ ! DLGA_LBDISPLAYTEXT Integer
+ ! DLGA_LBDISPLAYTEXTLEN Integer
+ ! DLGA_LBTEXT Integer
+ ! DLGA_LBTEXTLEN Integer
! DLGA_LBPAGEMODE Boolean
! DLGA_LBINDEXMODE Boolean
-
+
! DLGA_CBEDITABLE Boolean
- ! DLGA_CBRELAXMODE Integer
- ! DLGA_CBAUTOCOMPLETEMODE Integer
- ! DLGA_CBPOPUPMODE Integer
- ! DLGA_CBPOPUPSTATE Integer
+ ! DLGA_CBRELAXMODE Integer
+ ! DLGA_CBAUTOCOMPLETEMODE Integer
+ ! DLGA_CBPOPUPMODE Integer
+ ! DLGA_CBPOPUPSTATE Integer
! DLGA_GAUGEMIN Int|Str
! DLGA_GAUGEMAX Int|Str
@@ -683,7 +683,7 @@ do_dialog_run(void) /* int (int dialog, [string args]) */
current dialog is referenced.
Macro Returns:
- The 'dialog_delete()' primitive return non-zero on success,
+ The 'dialog_delete()' primitive return non-zero on success,
otherwise zero on error.
Macro Portability:
@@ -732,7 +732,7 @@ do_dialog_delete(void) /* int (int dialog) */
The 'dialog_exit()' primitive exits the current dialog.
Macro Parameters:
- retval - Integer return value, returned to the
+ retval - Integer return value, returned to the
original caller.
dialog - Optional dialog instance handle, if omitted the
@@ -834,7 +834,7 @@ inq_dialog(void) /* int () */
mutliple elements.
Macro Returns:
- The 'widget_set()' primitive returns the assigned value,
+ The 'widget_set()' primitive returns the assigned value,
otherwise NULL on error.
Macro Portability:
@@ -939,7 +939,7 @@ do_widget_set(void) /* ([int dialog], [int name|string name], declar
multiple elements.
Macro Returns:
- The 'widget_get()' primitive returns the assigned value,
+ The 'widget_get()' primitive returns the assigned value,
otherwise NULL on error.
Macro Portability:
diff --git a/gr/dialog_tty.c b/gr/dialog_tty.c
index 1d811ce2..177ca3ca 100644
--- a/gr/dialog_tty.c
+++ b/gr/dialog_tty.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_dialog_tty_c,"$Id: dialog_tty.c,v 1.26 2020/04/21 00:01:55 cvsuser Exp $")
+__CIDENT_RCSID(gr_dialog_tty_c,"$Id: dialog_tty.c,v 1.27 2021/10/18 13:14:34 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: dialog_tty.c,v 1.26 2020/04/21 00:01:55 cvsuser Exp $
+/* $Id: dialog_tty.c,v 1.27 2021/10/18 13:14:34 cvsuser Exp $
* Dialog manager, TTY interface.
*
*
@@ -391,9 +391,7 @@ dlg_close(DIALOG_t *d)
d->d_ucontrol = NULL;
c->cx_current = NULL;
- curbp = c->cx_obp; /* restore */
- curwp = c->cx_owp;
- set_hooked();
+ set_curwpbp(c->cx_owp, c->cx_obp); /* restore */
ttyframe_close(&c->cx_popup, TRUE);
ttyframe_close(&c->cx_base, TRUE);
@@ -431,8 +429,7 @@ ttyframe_create(TTYFrame_t *frame, int clear, const char *title, int x, int y, i
chk_free(cp);
}
- curwp = NULL; curbp = bp;
- set_hooked();
+ set_curwpbp(NULL, bp);
bp->b_termtype = LTERM_UNIX; /* UNIX style line feeds */
bp->b_imode = TRUE; /* localised insert-mode */
@@ -454,8 +451,7 @@ ttyframe_create(TTYFrame_t *frame, int clear, const char *title, int x, int y, i
* Create the window,
*/
if (-1 == window_create(W_POPUP, "", x, y, cols, rows)) {
- curwp = owp; curbp = obp;
- set_hooked();
+ set_curwpbp(owp, obp);
buf_kill(bp->b_bufnum);
return FALSE;
}
@@ -467,8 +463,7 @@ ttyframe_create(TTYFrame_t *frame, int clear, const char *title, int x, int y, i
WFSET(wp, WF_DIALOG);
attach_buffer(wp, bp);
wp->w_ctrl_state = 0; /* disable scrollbars etc */
- curwp = owp; curbp = obp;
- set_hooked();
+ set_curwpbp(owp, obp);
frame->f_wp = wp;
frame->f_bp = bp;
return TRUE;
@@ -480,9 +475,7 @@ ttyframe_focus(const TTYFrame_t *frame)
{
if (frame && frame->f_wp && frame->f_bp) {
if (curwp != frame->f_wp || curbp != frame->f_bp) {
- curwp = frame->f_wp;
- curbp = frame->f_bp;
- set_hooked();
+ set_curwpbp(frame->f_wp, frame->f_bp);
}
return TRUE;
}
@@ -534,9 +527,7 @@ dlg_controller(DIALOG_t *d, unsigned op, int p1, ...)
ttyframe_focus(&c->cx_base);
dlg_update(d);
- curbp = savbp;
- curwp = savwp;
- set_hooked();
+ set_curwpbp(savwp, savbp);
}
break;
diff --git a/gr/display.c b/gr/display.c
index a1b47102..295c35ee 100644
--- a/gr/display.c
+++ b/gr/display.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_display_c,"$Id: display.c,v 1.76 2020/04/13 14:29:18 cvsuser Exp $")
+__CIDENT_RCSID(gr_display_c,"$Id: display.c,v 1.81 2021/10/18 13:22:21 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: display.c,v 1.76 2020/04/13 14:29:18 cvsuser Exp $
+/* $Id: display.c,v 1.81 2021/10/18 13:22:21 cvsuser Exp $
* High level display interface.
*
*
@@ -1037,16 +1037,29 @@ vtmove(int row, int col)
* col - Cursor position on completion.
*
* Returns:
- * Resulting cursor location.
+ * Resulting cursor location, accounting for wide-characters,
+ * otherwise -1 if off screen.
*/
int
vtpute(vbyte_t ch, int col)
{
- if (vscreen)
- if (col >= 0 && col < ttcols()) {
+ if (vscreen) {
+ WChar_t wch = VBYTE_CHAR_GET(ch);
+ const int width = (wch > 0xff ? Wcwidth(wch) : 1);
+
+ if (col >= 0 && (col + width) <= ttcols()) {
vcell_set(vscreen[ttrows() - 1] + col, ch);
+ if (width >= 1) {
+ ++col;
+ if (width > 1) {
+ vcell_set(vscreen[ttrows() - 1] + col, CH_PADDING);
+ ++col;
+ }
+ }
+ return col;
}
- return col + 1;
+ }
+ return -1; //off-screen
}
@@ -2428,10 +2441,9 @@ winputch(WINDOW_t *wp, const vbyte_t ch, const vbyte_t attr, int rclip)
}
} else { /* MCHAR??? */
- int wcwidth = mchar_ucs_width(ch, 1);
-
+ int wcwidth = Wcwidth(ch);
while (wcwidth-- > 0) {
- winputm('?' | attr); /* ? or ?? */
+ winputm('?' | attr); /* ? or ?? */
}
}
@@ -2589,8 +2601,9 @@ draw_window(WINDOW_t *wp, int top, LINENO line, int end, const int bottom, int a
const int iscurrent = (curwp == wp ? TRUE : FALSE);
const int ledge = win_ledge(wp);
const int redge = win_redge(wp);
- const int syntax = (BFTST(wp->w_bufp, BF_SYNTAX) && wp->w_bufp->b_syntax);
-
+ const int syntax = (bp && BFTST(bp, BF_SYNTAX) && bp->b_syntax && //MCHAR???
+ bp->b_type != BFTYP_UTF16 && bp->b_type != BFTYP_UTF32);
+ /* syntax parser not wchar safe/FIXME */
const vbyte_t nattr = normalcolor(wp);
const vbyte_t lattr = (syntax ? VBYTE_ATTR(ATTR_COLUMN_LINENO) : nattr);
const vbyte_t sattr = (syntax ? VBYTE_ATTR(ATTR_COLUMN_STATUS) : nattr);
@@ -2609,7 +2622,7 @@ draw_window(WINDOW_t *wp, int top, LINENO line, int end, const int bottom, int a
wp->w_disp_anchor = NULL;
anchor.type = MK_NONE;
- if (wp->w_bufp) {
+ if (bp) {
if (iscurrent || WFTST(wp, WF_SHOWANCHOR)) {
if (anchor_get(wp, NULL, &anchor)) {
wp->w_disp_anchor = &anchor; /* active anchor */
@@ -2691,12 +2704,11 @@ draw_window(WINDOW_t *wp, int top, LINENO line, int end, const int bottom, int a
* Body
*/
saved_wp = curwp; /* requirement of lower level functionality (draw_line). */
- curwp = wp;
saved_bp = curbp;
- curbp = bp;
+ set_curwpbp(wp, bp);
for (; top <= end; ++top, ++line) {
- LINE_t *lp = vm_lock_line(line);
+ const LINE_t *lp = vm_lock_line2(line);
if (VTDRAW_DIRTY & actions) { /* skip clean/blank lines */
if (NULL == lp || 0 == lisdirty(lp)) {
@@ -2863,9 +2875,7 @@ draw_window(WINDOW_t *wp, int top, LINENO line, int end, const int bottom, int a
}
wp->w_disp_anchor = NULL;
- curwp = saved_wp; /* restore state */
- curbp = saved_bp;
- set_hooked();
+ set_curwpbp(saved_wp, saved_bp); /* restore state */
}
@@ -2905,9 +2915,10 @@ draw_title(const WINDOW_t *wp, const int top, const int line)
const unsigned char *title =
(unsigned char *)(!top ? wp->w_message :
(bp && BF2TST(bp, BF2_TITLE_FULL) && bp->b_fname[0] ? bp->b_fname : wp->w_title));
+ const unsigned char *titleend = (title ? title + strlen((const char *)title) : 0);
const char *suffix = NULL;
const vbyte_t col = framecolor(wp);
- int titlelen = (title && *title ? (int)strlen((const char *) title) : 0);
+ int titlelen = (title && *title ? (int)utf8_width(title, titleend) : 0); /*MCHAR*/
int left = 0;
int right = 0;
char numbuf[20];
@@ -2915,7 +2926,7 @@ draw_title(const WINDOW_t *wp, const int top, const int line)
/* read-only/modified suffix */
if (titlelen > 0) {
- if (bp) { /* MCHAR??? */
+ if (bp) {
if (BFTST(bp, BF_RDONLY)) {
if ((DC_ROSUFFIX & x_display_ctrl) || BF2TST(bp, BF2_SUFFIX_RO)) {
suffix = " (ro)";
@@ -2998,15 +3009,31 @@ draw_title(const WINDOW_t *wp, const int top, const int line)
int title_col = col;
if (WFTST(wp, WF_SELECTED) || (wp->w_status & WFTOP)) {
- title_col = titlecolor(wp); /* 'selected' window */
+ title_col = titlecolor(wp); /* 'selected' window */
}
ch = col | ' ';
vtputb(ch);
((WINDOW_t *)wp)->w_disp_cmap = x_base_cmap;
- while (*title && titlelen-- > 0) {
- vtputb(*title++ | title_col);
+
+// while (*title && titlelen-- > 0) {
+// vtputb(*title++ | title_col);
+// }
+ while (*title && titlelen > 0) { /* MCHAR */
+ const unsigned char *cend;
+ int cwidth;
+ int32_t wch;
+
+ if ((cend = charset_utf8_decode_safe(title, titleend, &wch)) > title &&
+ (cwidth = Wcwidth(wch)) >= 0) {
+ vtputb(wch | title_col);
+ titlelen -= cwidth;
+ title = cend;
+ continue; //next
+ }
+ break; //error
}
+
if (titlelen > 0 && suffix) {
while (*suffix && titlelen-- > 0) {
vtputb(*suffix++ | title_col);
@@ -3390,7 +3417,7 @@ draw_line(const vbyte_t nattr, const vbyte_t wattr,
wch = 0;
if ((wcp = mchar_decode_safe(iconv, ocp, end, &wch)) > ocp &&
- (wwidth = mchar_ucs_width(wch, 1)) >= 0) {
+ (wwidth = Wcwidth(wch)) >= 0) {
/*
* apply cursor rules and increment buffers
*/
@@ -4122,4 +4149,5 @@ do_screen_dump(void) /* int ([string filename], [string encoding]) */
acc_assign_int(0);
fclose(fp);
}
+
/*end*/
diff --git a/gr/echo.c b/gr/echo.c
index 29751683..56d94cb7 100644
--- a/gr/echo.c
+++ b/gr/echo.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_echo_c,"$Id: echo.c,v 1.63 2015/02/19 00:16:51 ayoung Exp $")
+__CIDENT_RCSID(gr_echo_c,"$Id: echo.c,v 1.72 2021/08/01 14:34:04 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: echo.c,v 1.63 2015/02/19 00:16:51 ayoung Exp $
+/* $Id: echo.c,v 1.72 2021/08/01 14:34:04 cvsuser Exp $
* Command/echo line implementation/interface.
*
*
@@ -40,6 +40,7 @@ __CIDENT_RCSID(gr_echo_c,"$Id: echo.c,v 1.63 2015/02/19 00:16:51 ayoung Exp $")
#include "kill.h"
#include "m_time.h"
#include "macros.h" /* macro_lookup */
+#include "mchar.h"
#include "main.h"
#include "map.h"
#include "playback.h"
@@ -68,7 +69,9 @@ struct _estate {
int vf_status;
int vf_values[4];
int position;
- char buffer[200];
+#define buffer_end(__state) \
+ (__state->buffer + (_countof(__state->buffer) - 1 /*nul*/))
+ WChar_t buffer[200];
MAGIC_t magic2;
};
@@ -78,31 +81,33 @@ static int ereplyask(const char *prompt, const char *defstr, char *
static int elineedit(const char *prompt, const char *defstr, char *buf, int nbuf, int one);
static void eprompt(int force, int buflen);
static void edisplay(void);
-static int eposition(const char *buf, int bpos, int left);
+
+static int eposition(const WChar_t *buf, int bpos, int bleft);
static int emaxcols(void);
static int eputc(int col, int c, vbyte_t attr);
-static int eputs(int col, vbyte_t *buf, int len, vbyte_t attr);
-
-static int estrlen(const char *str, int hilite);
-static int eprintable(const vbyte_t ch, vbyte_t *buf);
-
-static void ef_format(const char *fmt, char *cp, struct _estate *s);
-static char * ef_space(char *cp);
-static char * ef_integer(char *cp, int ivalue, int width);
-static char * ef_buffer(char *cp, const char *buf);
-static char * ef_ovmode(char *cp, const struct _estate *s);
-static char * ef_charvalue(char *cp, struct _estate *s);
-static char * ef_virtual(char *cp, struct _estate *s);
-static char * ef_imode(char *cp, const struct _estate *s);
-static char * ef_line(char *cp, const struct _estate *s);
-static char * ef_numlines(char *cp, const struct _estate *s);
-static char * ef_filemode(char *cp, const struct _estate *s);
-static char * ef_col(char *cp, const struct _estate *s);
-static char * ef_percent(char *cp, const struct _estate *s);
-static char * ef_time(char *cp, const struct _estate *s, int hour24);
-static char * ef_date(char *cp, const struct _estate *s, int format);
-static char * ef_version(char *cp, const struct _estate *s);
+static int eputs(int col, const vbyte_t *buf, int len, vbyte_t attr);
+
+static int eprintlen(const WChar_t *str);
+static int eprintable(const vbyte_t ch, vbyte_t *buf, int *buflen);
+
+static void ef_format(const char *fmt, struct _estate *s);
+static WChar_t * ef_space(WChar_t *cp, const struct _estate *s);
+static WChar_t * ef_buffer(WChar_t *cp, const char *buf, const struct _estate *s);
+static WChar_t * ef_utf8(WChar_t *cp, const char *buf, const struct _estate *s);
+static WChar_t * ef_integer(WChar_t *cp, int ivalue, int width, const struct _estate *s);
+static WChar_t * ef_ovmode(WChar_t *cp, const struct _estate *s);
+static WChar_t * ef_charvalue(WChar_t *cp, struct _estate *s);
+static WChar_t * ef_virtual(WChar_t *cp, struct _estate *s);
+static WChar_t * ef_imode(WChar_t *cp, const struct _estate *s);
+static WChar_t * ef_line(WChar_t *cp, const struct _estate *s);
+static WChar_t * ef_numlines(WChar_t *cp, const struct _estate *s);
+static WChar_t * ef_filemode(WChar_t *cp, const struct _estate *s);
+static WChar_t * ef_col(WChar_t *cp, const struct _estate *s);
+static WChar_t * ef_percent(WChar_t *cp, const struct _estate *s);
+static WChar_t * ef_time(WChar_t *cp, int hour24, const struct _estate *s);
+static WChar_t * ef_date(WChar_t *cp, int format, const struct _estate *s);
+static WChar_t * ef_version(WChar_t *cp, const struct _estate *s);
int xf_echoflags = /* echo line status */
E_CHARVALUE | E_VIRTUAL | E_LINE | E_COL | E_CURSOR | E_REMEMBER | E_TIME;
@@ -122,16 +127,19 @@ static struct _estate lc_state; /* current echo_line state */
static vbyte_t echo_color = ATTR_MESSAGE;
static vbyte_t echo_standout = 0;
-static unsigned char echo_line[EBUFSIZ*2]; /* echo line buffer */
-static unsigned char echo_attr[EBUFSIZ+2]; /* character attributes 0=normal,1=standout */
+#define ECHOLINESZ (MAX_CMDLINE + EBUFSIZ)
+
+static WChar_t wecho_line[ECHOLINESZ]; /* echo line buffer */
+static unsigned char echo_attr[ECHOLINESZ]; /* character attributes 0=normal,1=standout */
-static int echo_prompt; /* length of prompt, in characters */
+static int echo_prompt_len; /* length of prompt in characters */
+static int echo_prompt_width; /* display width of prompt, in characters */
static int echo_default; /* length of default abs() +active,-inactive */
static int echo_offset; /* displayed offset within echo line when prompt > vtcols */
-static char * echo_cmdline; /* pointer to string just typed in by user (see inq_cmd_line) */
+static const char * echo_cmdline; /* pointer to string just typed in by user (see inq_cmd_line) */
static char last_msg[MSG_SIZE]; /* last message printed. */
@@ -160,8 +168,8 @@ eyorn(const char *msg)
echo_color = ATTR_QUESTION;
while (1) {
ewprintf("%s [yn]? ", msg);
- s = (KEY)io_get_key(0);
- if ((s & RANGE_MASK) == RANGE_ASCII) {
+ s = (KEY) io_get_key(0);
+ if (IS_CHARACTER(s)) {
if (strchr("yYnN\033", s)) { /* Y[es], N[o] or ESC */
break;
}
@@ -427,7 +435,7 @@ equestion(const char *prompt, char *buf, int nbuf)
*/
static int
ereplyask(const char *prompt, const char *defstr,
- char *buf, int nbuf, int attr, int standout, int one)
+ char *buf, int bufsiz, int attr, int standout, int one)
{
const int saved_flags = trace_flags();
const int omsglevel = x_msglevel;
@@ -443,40 +451,44 @@ ereplyask(const char *prompt, const char *defstr,
echo_color = attr;
echo_standout = standout;
eprint(prompt, (defstr ? defstr : ""));
- if ('\001' == *prompt) {
- ++prompt; /* consume hilite marker \001 */
- }
-
- trace_log("ereplyask: <%s>(%d:%d)\n", prompt, nbuf, one);
if (nflags && 0 == (nflags & DB_PROMPT)) {
nflags = 0; /* disable debug prompt */
}
/* trigger start */
- if (!one) {
- static const char _prompt_begin[] = "_prompt_begin";
+ { const char *t_prompt = prompt;
- if (macro_lookup(_prompt_begin)) {
- char ebuf[EBUFSIZ + 20];
+ if ('\001' == *prompt) { /* hilite marker \001 */
+ ++t_prompt;
+ }
- sxprintf(ebuf, sizeof(ebuf), "%s \"%s\"", _prompt_begin, prompt);
- trace_flagsset(nflags);
- execute_str(ebuf);
- /*
- * TODO, BRIEF compat ---
- * The new default response should be returned as a
- * string if changed, otherwise return an integer/null
- * to indicate no change.
- */
- trace_flagsset(saved_flags);
- } else {
- trace_log("ereplyask: _prompt_begin not found\n");
+ trace_log("ereplyask: <%s>(%d:%d)\n", t_prompt, bufsiz, one);
+
+ if (! one) {
+ static const char _prompt_begin[] = "_prompt_begin";
+
+ if (macro_lookup(_prompt_begin)) {
+ char ebuf[EBUFSIZ + 20];
+
+ sxprintf(ebuf, sizeof(ebuf), "%s \"%s\"", _prompt_begin, t_prompt);
+ trace_flagsset(nflags);
+ execute_str(ebuf);
+ /*
+ * TODO, BRIEF compat ---
+ * The new default response should be returned as a
+ * string if changed, otherwise return an integer/null
+ * to indicate no change.
+ */
+ trace_flagsset(saved_flags);
+ } else {
+ trace_log("ereplyask: _prompt_begin not found\n");
+ }
}
}
/* line-editor implementation */
- ret = elineedit(prompt, defstr, buf, nbuf, one);
+ ret = elineedit(prompt, defstr, buf, bufsiz, one);
/* completion */
echo_standout = t_echo_standout;
@@ -566,7 +578,7 @@ ereplyask(const char *prompt, const char *defstr,
*
* Ctrl+V, Ctrl+Y (*) Paste from clipboard.
*
- * TODO:
+ * TODO (plus key mapping):
*
* Ctrl+C, Ctrl+W (*) Cut to clipboard.
*
@@ -587,38 +599,44 @@ ereplyask(const char *prompt, const char *defstr,
* otherwise TRUE with result contained within 'buf'.
*/
static int
-elineedit(const char *prompt, const char *defstr, char *buf, int bufsiz, int one)
+elineedit(const char *prompt, const char *defstr, char *result, int bufsiz, int one)
{
- char ndefstr[MAX_CMDLINE] = {0};
- int left = 0, bpos = 0, imode = TRUE;
- int first_key = TRUE;
- KEY c;
+ WChar_t buf[EBUFSIZ];
+ char ndefstr[EBUFSIZ];
+ int bleft = 0, bpos = 0, imode = TRUE;
+ int first_key = TRUE;
+ KEY c = 0;
+
+ assert(bufsiz >= 2 /*&& bufsiz <= EBUFSIZ*/);
+ if (bufsiz > _countof(buf)) bufsiz = _countof(buf);
- assert(bufsiz >= 2);
+ memset(buf, 0, sizeof(buf));
+ memset(ndefstr, 0, sizeof(ndefstr));
- memset(buf, 0, bufsiz); /* zap reply */
if (NULL == defstr) defstr = "";
- strxcpy(buf, defstr, bufsiz);
- --bufsiz; /* remove terminator */
+ Wcsfromutf8(defstr, buf, bufsiz);
last_msg[0] = '\0';
x_prompting = TRUE;
ecursor(imode);
ttcolornormal();
+ trace_log("elineedit:\n");
+
while (1) {
/* update prompt/cursor */
+ assert(bpos >= 0 && bpos <= bufsiz);
if (! first_key) {
if (0 == bpos) {
- echo_offset = left = 0; /* home */
+ echo_offset = bleft = 0; /* home */
}
- eprompt(FALSE, (int)strlen(buf));
- left = eposition(buf, bpos, left);
+ eprompt(FALSE, (int) Wcslen(buf));
+ bleft = eposition(buf, bpos, bleft);
}
/* next key */
ttflush();
- c = (KEY)io_get_key(0);
+ c = (KEY) io_get_key(0);
if (one) {
/*
@@ -628,7 +646,7 @@ elineedit(const char *prompt, const char *defstr, char *buf, int bufsiz, int one
*/
if (KEY_ESC != c) {
buf[0] = (c > 0x7f ? 0 : (char)c);
- buf[1] = '\0';
+ buf[1] = '\0';
goto done;
}
goto cancel;
@@ -639,13 +657,12 @@ elineedit(const char *prompt, const char *defstr, char *buf, int bufsiz, int one
* First key and it is a special one,
* then user has accepted the default prompt unmark.
*/
- case KEY_TAB: case CTRL_H:
- case KEY_HOME: case KEY_END:
- case KEY_WLEFT: case KEY_WRIGHT:
- case KEY_LEFT: case KEY_RIGHT:
- case 0x7f: case KEY_DEL:
- strxcpy(buf, defstr, bufsiz + 1);
- bpos = (int)strlen(buf);
+ case KEY_TAB: case CTRL_H:
+ case KEY_HOME: case KEY_END:
+ case KEY_WLEFT: case KEY_WRIGHT:
+ case KEY_LEFT: case KEY_RIGHT:
+ case KEY_DELETE: case KEY_DEL:
+ bpos = Wcsfromutf8(defstr, buf, bufsiz);
break;
/*
@@ -695,51 +712,64 @@ cancel:; ecursor(buf_imode(curbp));
case KEY_UP:
case WHEEL_UP:
case WHEEL_DOWN:
-badkey:; { const char *sacc;
- char *oecho_cmdline = echo_cmdline;
+badkey:; { const char *oecho_cmdline = echo_cmdline;
+ const int t_bufsiz = Wcslen(buf) * 4;
+ const char *sacc;
+ char *t_buf = NULL;
+
+ trace_log("elineedit: badkey\n");
+ if (t_bufsiz) {
+ if (NULL == (t_buf = malloc(t_bufsiz))) {
+ goto cancel;
+ }
+ Wcstoutf8(buf, t_buf, t_bufsiz);
+ }
key_cache_key(x_push_ref, c, FALSE);
trigger(REG_INVALID); /* old interface, use of _bad_key() preferred */
+
+ echo_cmdline = (t_buf ? t_buf : "");
x_prompting = FALSE;
- echo_cmdline = buf;
- execute_str("_bad_key"); /* XXX - should pass the keycode */
+ execute_str("_bad_key"); /* pass the keycode?? */
echo_cmdline = oecho_cmdline;
x_prompting = TRUE;
+ free(t_buf);
if (NULL == (sacc = acc_get_sval())) {
goto cancel;
}
strxcpy(ndefstr, sacc, sizeof(ndefstr));
- strxcpy(buf, sacc, bufsiz + 1);
+ Wcsfromutf8(sacc, buf, bufsiz);
+
eprint(prompt, ndefstr);
defstr = ndefstr;
first_key = TRUE;
}
- continue;
+ break;
case KEY_WLEFT: /* , cursor movement */
case KEY_WLEFT2:
- while (isspace(buf[bpos]) && bpos > 0) {
+ while (bpos > 0 && isspace(buf[bpos])) {
--bpos;
}
- while (!isspace(buf[bpos]) && bpos > 0) {
+ while (bpos > 0 && !isspace(buf[bpos])) {
--bpos;
}
break;
case KEY_WRIGHT: /* , cursor movement */
case KEY_WRIGHT2:
- while (isspace(buf[bpos]) && buf[bpos]) {
+ while (bpos < bufsiz && isspace(buf[bpos]) && buf[bpos]) {
++bpos;
}
- while (!isspace(buf[bpos]) && buf[bpos]) {
+ while (bpos < bufsiz && !isspace(buf[bpos]) && buf[bpos]) {
++bpos;
}
break;
case KEY_RIGHT: /* , cursor movement */
- if (buf[bpos]) {
+ if (bpos < bufsiz && buf[bpos]) {
++bpos;
}
break;
@@ -756,7 +786,7 @@ badkey:; { const char *sacc;
break;
case KEY_END: /* , cursor movement */
- bpos = (int)strlen(buf);
+ bpos = (int)Wcslen(buf);
break;
case ALT_I: /* , toggle insert/overstrike mode */
@@ -776,11 +806,11 @@ badkey:; { const char *sacc;
case KEY_DEL: /* , delete character under the cursor */
case 0x7F:
case CTRL_D: {
- char *bcursor = buf + bpos;
- size_t rlen = strlen(bcursor);
+ WChar_t *bcursor = buf + bpos;
+ size_t rlen = Wcslen(bcursor);
if (rlen) {
- if (--rlen) memmove(bcursor, bcursor + 1, rlen);
+ if (--rlen) Wmemmove(bcursor, bcursor + 1, rlen);
bcursor[rlen] = 0;
}
}
@@ -794,79 +824,123 @@ badkey:; { const char *sacc;
case ALT_D: /* , delete line/buffer */
case CTRL_X:
case CTRL_U:
- bpos = 0;
buf[0] = '\0';
+ bpos = 0;
break;
case KEY_INS: /* , insert scrap into prompt */
case KEY_PASTE:
case CTRL_V:
case CTRL_Y: {
- const char *cpp;
- int scount = 0;
- char *bcursor;
-
- k_seek();
- if ((scount = k_read(&cpp)) <= 0) {
- ttbeep();
- continue;
+ WChar_t t_buf[sizeof(buf)] = {0};
+ const char *scrap_buffer = NULL;
+ int scrap_size = 0;
+
+ if (bpos >= (bufsiz - 1)) {
+ ttbeep(); /* end-of-buffer */
+ break;
}
- while (estrlen(buf, FALSE) <= bufsiz && --scount) {
- if (bpos > bufsiz) {
- ttbeep();
- break;
+ k_seek(); /* MCHAR/???, utf8 assumption */
+ while (0 == (scrap_size = k_read(&scrap_buffer))) {
+ continue; /* first non-empty line */
+ }
+
+ if (scrap_size < 0 /*eof*/) {
+ ttbeep(); /* nothing available */
+
+ } else {
+ const int blen = Wcslen(buf);
+ const int trailing = (bpos < blen ? blen - bpos : 0);
+ const int remaining = bufsiz - (bpos + (imode ? trailing : 0));
+
+ assert(bpos <= blen);
+ if (remaining > imode) { /* space available, inc nul */
+ int copied;
+
+ memcpy(t_buf, buf, sizeof(buf));
+ if ((copied = Wcsfromutf8(scrap_buffer, buf + bpos, remaining)) > 0) {
+ assert((bpos + copied) < bufsiz);
+ if (trailing) {
+ const int binsert = bpos + copied;
+ if (imode) { /* append original */
+ assert((binsert + trailing) < bufsiz);
+ Wmemcpy(buf + binsert, t_buf + bpos, trailing + 1 /*nul*/);
+ } else { /* replace null with previous value */
+ if (binsert < blen) {
+ buf[binsert] = t_buf[binsert];
+ }
+ }
+ }
+ assert(Wcslen(buf) < (size_t)bufsiz);
+ }
+ scrap_size -= copied;
}
- bcursor = buf + bpos;
- if (0 == *bcursor) {
- bcursor[1] = '\0';
- } else if (imode) {
- memmove(bcursor + 1, bcursor, bufsiz - bpos);
+
+ if (scrap_size) {
+ ttbeep(); /* overflow */
}
- *bcursor = *cpp++;
- ++bpos;
}
}
break;
case 0:
case KEY_VOID:
- continue;
+ break;
+
+ case KEY_WINCH: /* resize event */
+ vtwinch(ttcols(), ttrows());
+ vtupdate();
+ elinecol(LC_DONTENABLE);
+ break;
case ALT_Q: /* , quote the next input character */
case CTRL_Q:
- c = (KEY)io_get_raw(0);
+ c = (KEY) io_get_raw(0);
if (0 == c || c >= KEY_VOID) {
- continue;
+ break;
}
/*FALLTHRU*/
- default: {
- if ((c & RANGE_MASK) != RANGE_ASCII) {
- goto badkey;
- }
+ default:
+ if (0 == IS_CHARACTER(c)) {
+ goto badkey; /* invalid key */
- if (0 == (c & 0xff) || bpos > bufsiz ||
- estrlen(buf, FALSE) > bufsiz) {
- ttbeep();
+ } else if (bpos >= (bufsiz - 1)) {
+ ttbeep(); /* end-of-buffer */
- } else {
- char *bcursor = buf + bpos;
-
- if (0 == *bcursor) {
- bcursor[1] = '\0';
- } else if (imode) {
- memmove(bcursor + 1, bcursor, bufsiz - bpos);
+ } else {
+ const int blen = Wcslen(buf);
+ const int trailing = (bpos < blen ? blen - bpos : 0);
+ const int remaining = bufsiz - (bpos + (imode ? trailing : 0));
+
+ assert(bpos <= blen); /* space available, minus nul */
+ if (remaining > imode) {
+ WChar_t *binsert = buf + bpos++;
+ if (*binsert) {
+ assert(trailing);
+ if (imode) { /* insert, otherwise replace */
+ assert((binsert + trailing) < (buf + bufsiz));
+ Wmemmove(binsert + 1, binsert, trailing + 1 /*nul*/);
+ }
+ } else {
+ binsert[1] = '\0'; /* end-of-string */
}
- *bcursor = (char) c;
- ++bpos;
+ *binsert = c;
+ assert(Wcslen(buf) < (size_t)bufsiz);
+
+ } else {
+ ttbeep(); /* overflow */
}
}
break;
}
}
+
done:;
- assert(0 == buf[bufsiz]);
+ assert(Wcslen(buf) < (size_t)bufsiz);
+ Wcstoutf8(buf, result, bufsiz);
+ assert((int)strlen(result) < bufsiz);
x_prompting = FALSE;
ecursor(buf_imode(curbp));
return TRUE;
@@ -888,7 +962,7 @@ eprompt(int force, int buflen)
{
const int odisabled = lc_disabled;
const int ooffset = echo_offset;
- const int length = echo_prompt + /* total length */
+ const int length = echo_prompt_width + /* total length */
(buflen >= 0 ? buflen : echo_default);
/* disable line/col? */
@@ -902,7 +976,7 @@ eprompt(int force, int buflen)
echo_offset = 0; /* home */
} else { /* >3/4 shall be prompt */
- echo_offset = echo_prompt - (ttcols() * 3) / 4;
+ echo_offset = echo_prompt_width - (ttcols() * 3) / 4;
if (echo_offset < 0) {
echo_offset = 0;
}
@@ -927,64 +1001,66 @@ eprompt(int force, int buflen)
* Parameters:
* buf - Address of user buffer.
* bpos - Current buffer position (cursor).
- * left - Storage of working variable contained the 'left' margin.
+ * bleft - Storage of working variable contained the 'left' margin.
*
* Return:
- * New 'left' value.
+ * Resultng 'left' value.
*/
static int
-eposition(const char *buf, int bpos, int left)
+eposition(const WChar_t *buf, int bpos, int bleft)
{
const vbyte_t attr = VBYTE_ATTR(echo_color);
- int col = echo_prompt - echo_offset; /* user buffer base column */
+ int col = echo_prompt_width - echo_offset; /* user buffer base column */
int cursor = -1; /* cursor position */
- int pos = 0;
- int partial = 0;
- int len, i;
+ int i, pos = 0;
- /* figure out where the cursor is going to land */
+ /*
+ * Size output buffer ...
+ */
for (i = 0; i < bpos && buf[i];) {
- pos += eprintable(buf[i++], NULL);
+ pos += eprintable(buf[i++], NULL, NULL);
}
- /* if cursor off the screen then we need to reframe the users input */
- if (bpos < left) {
- while (i > 0 && left > bpos) {
- pos -= eprintable(buf[--i], NULL);
- --left;
+ /*
+ * if cursor off screen, reframe
+ */
+ if (bpos < bleft) {
+ while (i > 0 && bleft > bpos) {
+ pos -= eprintable(buf[--i], NULL, NULL);
+ --bleft;
}
- } else if (col + pos - left >= lc_column) {
+ } else if (col + pos - bleft >= lc_column) {
pos = lc_column;
-
- --i;
- while (pos > col && i >= 0) {
- pos -= eprintable(buf[i--], NULL);
- }
- ++i;
- if (pos < col) {
- partial = col - pos;
+ while (pos >= col && i >= 0) {
+ const int width = eprintable(buf[i--], NULL, NULL);
+ if ((pos - width) <= col) {
+ ++i;
+ break;
+ }
+ pos -= width;
}
- ++i;
- left = i;
+ bleft = i;
}
- /* redraw the line, pad with trailing spaces */
- buf += left;
- for (i = left; col < lc_column; ++i) {
+ /*
+ * Redraw prompt, pad with trailing spaces.
+ */
+ buf += bleft;
+ for (i = bleft; col < lc_column; ++i) {
const int ch = (*buf ? *buf++ : ' ');
- vbyte_t vbuf[10] = {0};
+ vbyte_t vbuf[16] = {0};
+ int vlen = _countof(vbuf);
- if (i == bpos) { /* cursor located */
- cursor = col;
- }
- len = eprintable(ch, vbuf);
- col = eputs(col, vbuf + partial, len - partial, attr);
- partial = 0;
+ if (i == bpos) cursor = col; /* cursor located */
+
+ eprintable(ch, vbuf, &vlen);
+ col = eputs(col, vbuf, vlen, attr);
}
+
vtupdate_bottom(cursor);
- return left;
+ return bleft;
}
@@ -1003,28 +1079,35 @@ edisplay(void)
const vbyte_t normal = VBYTE_ATTR(echo_color);
const vbyte_t standout = VBYTE_ATTR(echo_standout);
const vbyte_t completion = VBYTE_ATTR(ATTR_PROMPT_COMPLETE);
- unsigned char *cp, *ap, *ep; /* buffer working pointers */
- int cursor, col = 0;
+ const WChar_t *cp, *ep; /* buffer working pointers */
+ const unsigned char *ap;
+ int offset = echo_offset, cursor, col = 0;
- trace_log("edisplay: prompt[%d]:<", echo_prompt);
+ trace_log("edisplay: prompt[%d,%d]:<", offset, echo_prompt_width);
- ep = echo_line + echo_prompt; /* display prompt, hilite if required */
- for (cp = echo_line + echo_offset, ap = echo_attr + echo_offset; *cp; ++cp, ++ap) {
+ for (cp = wecho_line, ep = cp + echo_prompt_len,
+ ap = echo_attr; *cp; ++cp, ++ap) {
+ const int32_t wch = *cp;
+
+ if (offset > 0) { /* consume off-screen */
+ --offset;
+ continue;
+ }
if (lc_column && col >= lc_column) {
break; /* trim */
}
- trace_log("%c", *cp);
+ trace_log("%c", wch);
- if (cp < ep && *ap && standout) {
- col = eputc(col, *cp, standout); /* prompt */
+ if (standout && col < echo_prompt_width && *ap) {
+ col = eputc(col, wch, standout); /* prompt */
} else if (echo_default > 0 && cp >= ep) {
- col = eputc(col, *cp, completion); /* default/completion */
+ col = eputc(col, wch, completion); /* default/completion */
} else {
- col = eputc(col, *cp, normal); /* user text */
+ col = eputc(col, wch, normal); /* user text */
}
}
@@ -1041,32 +1124,6 @@ edisplay(void)
}
-/* Function: estrlen
- * Determine the display length of the specified buffer 'str'.
- *
- * Parameters:
- * str - Buffer.
- * hilite - TRUE or FALSE, process hilite markers.
- *
- * Returns:
- * Length of the buffer in bytes.
- */
-static int
-estrlen(const char *str, int hilite)
-{
- int ch, len = 0;
-
- if (str) {
- while (0 != (ch = *str++)) {
- if (! hilite || '^' != ch) {
- len += eprintable((ch >= ' ' ? ch : (ch | 0x80)), NULL);
- }
- }
- }
- return len;
-}
-
-
/* Function: inq_message
* inq_message primitive.
*
@@ -1102,7 +1159,10 @@ estrlen(const char *str, int hilite)
void
inq_message(void)
{
- acc_assign_str((char *)echo_line, -1);
+ char t_echo_line[ECHOLINESZ] = {0};
+
+ Wcstoutf8(wecho_line, t_echo_line, sizeof(t_echo_line));
+ acc_assign_str((const char *)t_echo_line, -1);
}
@@ -1170,8 +1230,7 @@ inq_prompt(void)
none
Macro Returns:
- The 'inq_cmd_line' returns a string containing the current
- prompt.
+ The 'inq_cmd_line' returns a string containing the current prompt.
Macro Portability:
n/a
@@ -1184,8 +1243,12 @@ inq_cmd_line(void)
{
if (echo_cmdline) {
acc_assign_str((const char *)echo_cmdline, -1);
+
} else {
- acc_assign_str((const char *)(echo_line + echo_prompt), -1);
+ char t_cmd_line[EBUFSIZ] = {0};
+
+ Wcstoutf8(wecho_line + echo_prompt_len, t_cmd_line, sizeof(t_cmd_line));
+ acc_assign_str((const char *)t_cmd_line, -1);
}
}
@@ -1213,8 +1276,7 @@ inq_cmd_line(void)
none
Macro Returns:
- The 'inq_line_col()' primitive returns the current echo line
- status.
+ The 'inq_line_col()' primitive returns the current echo line status.
Macro Portability:
n/a
@@ -1225,7 +1287,10 @@ inq_cmd_line(void)
void
inq_line_col(void)
{
- acc_assign_str(lc_state.buffer, -1);
+ char t_line_col[_countof(lc_state.buffer) * 4] = {0};
+
+ Wcstoutf8(lc_state.buffer, t_line_col, sizeof(t_line_col));
+ acc_assign_str(t_line_col, -1);
}
@@ -1284,7 +1349,6 @@ ewprintx(const char *fmt, ...)
void
eeprintf(const char *fmt, ...)
{
-// const vbyte_t t_echo_color = echo_color;
char iobuf[EBUFSIZ];
va_list ap;
@@ -1298,7 +1362,6 @@ eeprintf(const char *fmt, ...)
void
eeprintx(const char *fmt, ...)
{
-// const vbyte_t t_echo_color = echo_color;
const int xerrno = errno;
char iobuf[EBUFSIZ];
va_list ap;
@@ -1413,40 +1476,37 @@ eprint(const char *prompt, const char *defstr)
}
}
- /* save prompt */
- echo_prompt = estrlen(prompt, hilite);
+ /*
+ * import prompt, default and display
+ */
+ echo_prompt_len = Wcsfromutf8(prompt, wecho_line, _countof(wecho_line));
memset(echo_attr, 0, sizeof(echo_attr));
- if (hilite) {
- const unsigned char *p = (const unsigned char *)prompt;
- unsigned char *echo = echo_line,
- *end = echo + (sizeof(echo_line) - 1);
- unsigned char *attr = echo_attr;
- unsigned char ch;
-
- while (echo < end && 0 != (ch = *p++)) {
- if ('^' == ch) { /* hilite next character */
- *attr = 1;
- } else {
- *echo++ = ch;
- ++attr;
+ if (hilite) {
+ WChar_t *cp = wecho_line, *out = cp,
+ *end = cp + (_countof(wecho_line) - 1), wch;
+ unsigned char *ap = echo_attr;
+
+ while (cp < end && 0 != (wch = *cp++)) {
+ if ('^' == wch && *cp) { /* hilite next character */
+ --echo_prompt_len;
+ *ap = 1;
+ continue;
}
+ *out++ = wch;
+ ++ap;
}
- *echo = 0;
- } else {
- strxcpy((char *)echo_line, prompt, sizeof(echo_line));
+ *out = 0;
}
- /* save default (if any) */
+ echo_prompt_width = eprintlen(wecho_line); /* display width */
+
if (!defstr || !*defstr) {
echo_default = 0; /* no default */
-
} else {
- strxcat((char *)echo_line, defstr, sizeof(echo_line));
- echo_default = (int)strlen(defstr);
+ echo_default = Wcsfromutf8(defstr, wecho_line + echo_prompt_len, _countof(wecho_line) - echo_prompt_len);
}
- /* display */
eprompt(TRUE, -1);
}
@@ -1473,9 +1533,8 @@ emaxcols(void)
/* Function: eputc
- * Write to the virtual display, using the existing attribute. The
- * specified character is converted to it printable form prior to being
- * displayed.
+ * Write to the virtual display, using the existing attribute.
+ * The specified character is converted to it printable form prior to being displayed.
*
* Parameter:
* pp - Cursor.
@@ -1488,12 +1547,14 @@ emaxcols(void)
static int
eputc(int col, int c, vbyte_t attr)
{
- vbyte_t vbuf[10] = {0};
+ vbyte_t vbuf[16] = {0};
+ int vlen = _countof(vbuf);
if ('\r' == c || '\n' == c) {
return col;
}
- return eputs(col, vbuf, eprintable(c, vbuf), attr);
+ eprintable(c, vbuf, &vlen);
+ return eputs(col, vbuf, vlen, attr);
}
@@ -1510,7 +1571,7 @@ eputc(int col, int c, vbyte_t attr)
* Resulting cursor position.
*/
static int
-eputs(int col, vbyte_t *buf, int len, vbyte_t attr)
+eputs(int col, const vbyte_t *buf, int len, vbyte_t attr)
{
assert(col >= 0);
assert(col < ttcols());
@@ -1518,13 +1579,12 @@ eputs(int col, vbyte_t *buf, int len, vbyte_t attr)
assert(lc_column <= ttcols());
if (col >= 0) {
- while (len-- > 0) {
- if (col < lc_column) {
- if (vtpute((vbyte_t)(*buf++ | attr), col) < 0) {
- break; /* error, abort */
- }
- ++col;
+ while (len-- > 0 && col < lc_column) {
+ const int ncol = vtpute((vbyte_t)(*buf++ | attr), col);
+ if (-1 == ncol) {
+ break; /* off-screen */
}
+ col = ncol;
}
}
return col;
@@ -1628,11 +1688,11 @@ elinecol(int flags)
state.buffer[0] = '\0';
if (xf_echofmt && (E_FORMAT & xf_echoflags)) {
- ef_format(xf_echofmt, state.buffer, &state);
+ ef_format(xf_echofmt, &state);
} else {
const int echoflags = xf_echoflags;
- char *cp = state.buffer;
+ WChar_t *cp = state.buffer;
if (curwp && W_TILED == curwp->w_type) {
if (echoflags & E_CHARVALUE) {
@@ -1644,15 +1704,15 @@ elinecol(int flags)
}
if (echoflags & E_LINE) { /* line */
- cp = ef_line(ef_space(cp), &state);
+ cp = ef_line(ef_space(cp, &state), &state);
}
if (echoflags & E_COL) { /* column */
- cp = ef_col(ef_space(cp), &state);
+ cp = ef_col(ef_space(cp, &state), &state);
}
if (echoflags & E_PERCENT) { /* cursor percentage within file */
- cp = ef_percent(ef_space(cp), &state);
+ cp = ef_percent(ef_space(cp, &state), &state);
}
if (echoflags & E_CURSOR) {
@@ -1660,48 +1720,52 @@ elinecol(int flags)
}
if ((echoflags & E_REMEMBER) && x_rem_string[0] != ' ') {
- cp = ef_buffer(cp, x_rem_string); /* RE/PA */
- cp = ef_space(cp);
+ cp = ef_buffer(cp, x_rem_string, &state); /* RE/PA */
+ cp = ef_space(cp, &state);
}
if (echoflags & (E_TIME|E_TIME24)) { /* current time */
- cp = ef_time(ef_space(cp), &state, (E_TIME24 & echoflags) ? TRUE : FALSE);
+ cp = ef_time(ef_space(cp, &state), (E_TIME24 & echoflags) ? TRUE : FALSE, &state);
}
}
assert(ESTATE_MAGIC == state.magic);
assert(ESTATE_MAGIC == state.magic2);
- lc_length = (int)strlen(state.buffer); /* line length */
+ lc_length = (int)Wcslen(state.buffer); /* line length */
assert(lc_length < (int) sizeof(state.buffer));
/* update */
lc_column = emaxcols() - lc_length; /* left column */
if ((LC_FORCE & flags) || lc_state.position != lc_column ||
- 0 != strcmp(lc_state.buffer, state.buffer)) {
+ 0 != Wcscmp(lc_state.buffer, state.buffer)) {
const vbyte_t attr = VBYTE_ATTR(ATTR_ECHOLINE);
- const char *cp;
+ const WChar_t *cp;
int col = 0;
/* erase characters longer needed */
if (0 == lc_state.position || lc_state.position >= lc_column) {
col = lc_column;
} else {
col += lc_state.position;
- while (col < lc_column) {
- vtpute(' ' | attr, col++);
+ while (col >= 0 && col < lc_column) {
+ const int ncol = vtpute(' ' | attr, col);
+ if (-1 == ncol) {
+ break; /* off-screen */
+ }
+ col = ncol;
}
}
- for (cp = state.buffer; *cp; ++cp) { /* now draw in the line/col string */
- vtpute(*cp | attr, col++);
+ for (cp = state.buffer; *cp; ++cp) {
+ col = vtpute(*cp | attr, col); /* now draw in the line/col string */
}
if (! ttlastsafe()) { /* clear last character */
- vtpute(' ' | VBYTE_ATTR(ATTR_NORMAL), col++);
+ col = vtpute(' ' | VBYTE_ATTR(ATTR_NORMAL), col);
}
vtupdate_bottom(-1); /* updated */
- strcpy(lc_state.buffer, state.buffer);
+ Wcscpy(lc_state.buffer, state.buffer);
lc_state.position = lc_column;
}
}
@@ -1787,7 +1851,7 @@ elinecol(int flags)
The virtual character status is represented by one of the
following otherwise blank if a normal character.
- X - Virtual space, for example logical space created as
+ X - Virtual space, for example logical space created as
the result of tab expansion.
$ - End of line.
@@ -2191,7 +2255,7 @@ inq_echo_format(void) /* string () */
/* Function: infof_truncated
- * Print a message contained a filenamet, truncating the filename
+ * Print a message contained a filename, truncating the filename
* if too long for the echo line.
*
* The format argument must be a sprintf() style string containing
@@ -2326,6 +2390,29 @@ errorfx(const char *fmt, ...)
}
+/* Function: eprintlen
+ * Determine the display length of the specified buffer 'str'.
+ *
+ * Parameters:
+ * str - Buffer.
+ *
+ * Returns:
+ * Length of the buffer in bytes.
+ */
+static int
+eprintlen(const WChar_t *str)
+{
+ WChar_t ch;
+ int len = 0;
+ if (str) {
+ while (0 != (ch = *str++)) {
+ len += eprintable(ch, NULL, NULL);
+ }
+ }
+ return len;
+}
+
+
/* Function: eprintable
* Converts a character to a printable format taking into account whether
* the terminal can support printable 8-bit chars, etc.
@@ -2333,17 +2420,18 @@ errorfx(const char *fmt, ...)
* Parameters:
* ch - Character value.
* buf - Destination buffer.
+ * buflen - Length, in bytes, of the output buffer.
*
* Returns:
- * length of the printed version.
+ * Display width.
*/
static int
-eprintable(const vbyte_t c, vbyte_t *buf)
+eprintable(const vbyte_t c, vbyte_t *buf, int *buflen)
{
const vbyte_t attr = VBYTE_ATTR_GET(c);
vbyte_t ch = VBYTE_CHAR_GET(c);
- char cp[32]; /* MCHAR */
- int len = 0;
+ char t_buffer[32];
+ int idx, len = 0;
if (ch <= 0xff) {
/*
@@ -2354,20 +2442,19 @@ eprintable(const vbyte_t c, vbyte_t *buf)
len = mc->mc_length;
if (buf) {
const unsigned char *mccp = (unsigned char *) mc->mc_str;
- int idx;
-
- if (NULL == cp) {
+ if (NULL == mccp) {
if ((ch = mc->mc_chr) > 0 && ch < 0x80) {
*buf++ = ch | attr;
} else {
goto ischaracter;
}
} else {
- assert(len <= 10);
+ assert(len < *buflen);
for (idx = 0; idx < len; ++idx) {
*buf++ = mccp[idx] | attr;
}
}
+ *buflen = len;
}
return len;
}
@@ -2376,14 +2463,24 @@ eprintable(const vbyte_t c, vbyte_t *buf)
* extended character values
*/
ischaracter:;
- len = sxprintf(cp, sizeof(cp), "u%04x", ch);
+ if (vtisunicode() || vtisutf8()) {
+ const int width = Wcwidth(ch);
+ if (width >= 0) {
+ if (buf) {
+ buf[0] = (ch & VBYTE_CHAR_MASK) | attr;
+ buf[1] = 0;
+ *buflen = 1;
+ }
+ return width;
+ }
+ }
+ len = sxprintf(t_buffer, sizeof(t_buffer), "u%04x", ch);
if (buf) {
- int idx;
-
- assert(len <= 10);
+ assert(len < *buflen);
for (idx = 0; idx < len; ++idx) {
- *buf++ = cp[idx] | attr;
+ *buf++ = t_buffer[idx] | attr;
}
+ *buflen = len;
}
return len;
}
@@ -2414,14 +2511,15 @@ eredraw(void)
* Parameters:
* fmt - Echo line format specification.
* cp - Buffer pointer.
- * state - State information, buffer and time/date.
+ * status - Edit state information, buffer and time/date.
*
* Returns:
* nothing
*/
static void
-ef_format(const char *fmt, char *cp, struct _estate *state)
+ef_format(const char *fmt, struct _estate *s)
{
+ WChar_t *cp = s->buffer;
if (fmt) {
char ch;
@@ -2474,7 +2572,7 @@ ef_format(const char *fmt, char *cp, struct _estate *state)
case 1: /* Number as decimal */
break;
default: /* Title */
- cp = ef_buffer(cp, curbp->b_title);
+ cp = ef_utf8(cp, curbp->b_title, s);
break;
}
}
@@ -2502,90 +2600,90 @@ ef_format(const char *fmt, char *cp, struct _estate *state)
case 'n': /* File name with directory */
if (curbp) {
- cp = ef_buffer(cp, curbp->b_fname);
+ cp = ef_utf8(cp, curbp->b_fname, s);
}
break;
case 'N': /* File name without the directory */
if (curbp && curbp->b_fname) {
- cp = ef_buffer(cp, sys_basename(curbp->b_fname));
+ cp = ef_utf8(cp, sys_basename(curbp->b_fname), s);
}
break;
case 'p': /* Percent string */
- cp = ef_percent(cp, state);
+ cp = ef_percent(cp, s);
break;
case 'c': /* Column number */
switch (modifier) {
case 1: /* xxx */
- cp = ef_integer(cp, state->bf_col, 0);
+ cp = ef_integer(cp, s->bf_col, 0, s);
break;
default: /* Col: xxx */
- cp = ef_col(cp, state);
+ cp = ef_col(cp, s);
}
break;
case 'm': /* Mode string (i.e. --rw-rw-rw) */
- cp = ef_filemode(cp, state);
+ cp = ef_filemode(cp, s);
break;
case 'o': /* Overwrite mode, " OV" otherwise "" */
- cp = ef_ovmode(cp, state);
+ cp = ef_ovmode(cp, s);
break;
case 'O': /* Overwrite/insert flag - like %o, but shows OV/RE */
- cp = ef_imode(cp, state);
+ cp = ef_imode(cp, s);
break;
case 'C': /* Character value */
- cp = ef_charvalue(cp, state);
+ cp = ef_charvalue(cp, s);
break;
case 'V': /* Virtual character indicator */
- cp = ef_virtual(cp, state);
+ cp = ef_virtual(cp, s);
break;
case 'r': /* Remember flag */
if (x_rem_string[0] != ' ') {
- cp = ef_buffer(cp, x_rem_string);
- cp = ef_space(cp);
+ cp = ef_buffer(cp, x_rem_string, s);
+ cp = ef_space(cp, s);
}
break;
case 'l': /* Line number */
switch (modifier) {
case 1: /* xxx */
- cp = ef_integer(cp, state->bf_line, 0);
+ cp = ef_integer(cp, s->bf_line, 0, s);
break;
default: /* Line: xxx */
- cp = ef_line(cp, state);
+ cp = ef_line(cp, s);
}
break;
case 'L': /* Number of lines in the file */
- cp = ef_numlines(cp, state);
+ cp = ef_numlines(cp, s);
break;
case 't': /* Time (12 or 24 hour) */
- cp = ef_time(cp, state, modifier ? TRUE : FALSE);
+ cp = ef_time(cp, modifier ? TRUE : FALSE, s);
break;
case 'd': /* Date, optional format */
- cp = ef_date(cp, state, modifier);
+ cp = ef_date(cp, modifier, s);
break;
case 'v': /* Version */
- cp = ef_version(cp, state);
+ cp = ef_version(cp, s);
break;
case 'Y': /* Year */
switch (modifier) {
case 1: /* YY */
- cp = ef_integer(cp, state->tm_year%100, 2);
+ cp = ef_integer(cp, s->tm_year%100, 2, s);
break;
default: /* YYYY */
- cp = ef_integer(cp, state->tm_year, 4);
+ cp = ef_integer(cp, s->tm_year, 4, s);
break;
}
break;
@@ -2593,16 +2691,16 @@ ef_format(const char *fmt, char *cp, struct _estate *state)
case 'M': /* Month of the year */
switch (modifier) {
case 3: /* Abbrev */
- cp = ef_buffer(cp, tm_month_abbrev(state->tm_month - 1));
+ cp = ef_buffer(cp, tm_month_abbrev(s->tm_month - 1), s);
break;
case 2: /* Name */
- cp = ef_buffer(cp, tm_month_name(state->tm_month - 1));
+ cp = ef_buffer(cp, tm_month_name(s->tm_month - 1), s);
break;
case 1: /* M[M] */
- cp = ef_integer(cp, state->tm_month, 0);
+ cp = ef_integer(cp, s->tm_month, 0, s);
break;
default: /* MM */
- cp = ef_integer(cp, state->tm_month, 2);
+ cp = ef_integer(cp, s->tm_month, 2, s);
break;
}
break;
@@ -2610,16 +2708,16 @@ ef_format(const char *fmt, char *cp, struct _estate *state)
case 'D': /* Day of the month */
switch (modifier) {
case 3: /* Abbrev */
- cp = ef_buffer(cp, tm_day_abbrev(state->tm_day - 1));
+ cp = ef_buffer(cp, tm_day_abbrev(s->tm_day - 1), s);
break;
case 2: /* Name */
- cp = ef_buffer(cp, tm_day_abbrev(state->tm_day - 1));
+ cp = ef_buffer(cp, tm_day_abbrev(s->tm_day - 1), s);
break;
case 1: /* D[D] */
- cp = ef_integer(cp, state->tm_day, 0);
+ cp = ef_integer(cp, s->tm_day, 0, s);
break;
default: /* DD */
- cp = ef_integer(cp, state->tm_day, 2);
+ cp = ef_integer(cp, s->tm_day, 2, s);
break;
}
break;
@@ -2640,77 +2738,107 @@ ef_format(const char *fmt, char *cp, struct _estate *state)
*
* Parameters:
* cp - Echo-line buffer cursor.
+ * s - Edit state.
*
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_space(char *cp)
+static WChar_t *
+ef_space(WChar_t *cp, const struct _estate *s)
{
- *cp++ = ' ';
- *cp = 0;
+ const WChar_t *end = buffer_end(s);
+ if (cp < end) {
+ *cp++ = ' ';
+ *cp = 0;
+ }
return cp;
}
-/* Function: ef_integer
- * Insert an integer attribute into the echo_line buffer.
+/* Function: ef_buffer
+ * Insert the specfied buffer 'buf' into the echo_line buffer.
*
* Parameters:
* cp - Echo-line buffer cursor.
- * ivalue - Integer value.
- * width - Optional field width.
+ * buf - Buffer to be inserted.
+ * s - Edit state.
*
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_integer(char *cp, int ivalue, int width)
+static WChar_t *
+ef_buffer(WChar_t *cp, const char *buf, const struct _estate *s)
{
- if (width > 0) {
- sprintf(cp, "%0*d", width, ivalue);
- } else if (width < 0) {
- sprintf(cp, "%*d", width * -1, ivalue);
- } else {
- sprintf(cp, "%d", ivalue);
+ const WChar_t *end = buffer_end(s);
+ if (buf && cp < end) {
+ WChar_t c;
+ while (cp < end && 0 != (c = *buf++)) {
+ *cp++ = c;
+ }
+ *cp = 0;
}
- return cp + strlen(cp);
+ return cp;
}
-/* Function: ef_buffer
- * Insert the specfied buffer 'buf' into the echo_line buffer.
+/* Function: ef_utf8
+ * Insert the specfied utf8 encoded buffer 'buf' into the echo_line buffer.
*
* Parameters:
* cp - Echo-line buffer cursor.
* buf - Buffer to be inserted.
+ * s - Edit state.
+ *
+ * Returns:
+ * resulting buffer cursor.
+ */
+static WChar_t *
+ef_utf8(WChar_t *cp, const char *buf, const struct _estate *s)
+{
+ return cp + (buf ? Wcsfromutf8(buf, cp, buffer_end(s) - cp) : 0);
+}
+
+
+/* Function: ef_integer
+ * Insert an integer attribute into the echo_line buffer.
+ *
+ * Parameters:
+ * cp - Echo-line buffer cursor.
+ * ivalue - Integer value.
+ * width - Optional field width.
+ * s - Edit state.
*
* Returns:
* resulting buffer cursor
*/
-static char *
-ef_buffer(char *cp, const char *buf)
+static WChar_t *
+ef_integer(WChar_t *cp, int ivalue, int width, const struct _estate *s)
{
- if (buf) {
- while ((*cp = *buf++) != '\0') {
- ++cp;
- }
+ char t_buffer[32];
+ if (width > 0) {
+ sprintf(t_buffer, "%0*d", width, ivalue);
+ } else if (width < 0) {
+ sprintf(t_buffer, "%*d", width * -1, ivalue);
+ } else {
+ sprintf(t_buffer, "%d", ivalue);
}
- return cp;
+ return ef_buffer(cp, t_buffer, s);
}
+
/* Function: ef_ovmode
* Insert the ovmode into the echo_line buffer.
*
* Parameters:
* cp - Echo-line buffer cursor.
+ * s - Edit state.
*
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_ovmode(char *cp, const struct _estate *s)
+static WChar_t *
+ef_ovmode(WChar_t *cp, const struct _estate *s)
{
__CUNUSED(s)
if (0 == x_pt.pt_icursor[0]) { /* visual cursor not available */
@@ -2730,17 +2858,20 @@ ef_ovmode(char *cp, const struct _estate *s)
*
* Parameters:
* cp - Character value.
+ * s - Edit state.
*
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_charvalue(char *cp, struct _estate *s)
+static WChar_t *
+ef_charvalue(WChar_t *cp, struct _estate *s)
{
int vstatus, charvalue;
+ char t_buffer[32];
__CUNUSED(s)
+ t_buffer[0] = 0;
if (-999 == (vstatus = s->vf_status)) { /* loaded? */
s->vf_status = vstatus = line_current_status(s->vf_values, 4);
}
@@ -2748,42 +2879,44 @@ ef_charvalue(char *cp, struct _estate *s)
if (0 == (BUFFERVSTATUS_ILLEGAL & vstatus)) {
if ((BUFFERVSTATUS_EOL|BUFFERVSTATUS_XEOL|BUFFERVSTATUS_PEOL) & vstatus) {
- return cp + sprintf(cp, " EOL "); /* */
+ strcpy(t_buffer, " EOL "); /* */
} else if (BUFFERVSTATUS_EOF == vstatus) {
- return cp + sprintf(cp, " EOF "); /* */
+ strcpy(t_buffer, " EOF "); /* */
} else if (charvalue <= 0) {
- return cp + sprintf(cp, " NUL ");
+ strcpy(t_buffer, " NUL ");
/* control */
} else if (charvalue <= 0x1f) {
- return cp + sprintf(cp, " ^%c ", 'A' + (charvalue - 1));
+ sprintf(t_buffer, " ^%c ", 'A' + (charvalue - 1));
/* ascii */
} else if (charvalue <= 0x7f && isprint(charvalue)) {
- return cp + sprintf(cp, " [%c] ", charvalue);
+ sprintf(t_buffer, " [%c] ", charvalue);
}
}
- if (0 == charvalue) { /* others */
- strcpy(cp, "u0000 ");
- } else {
- unsigned i;
+ if (0 == t_buffer[0]) {
+ if (0 == charvalue) { /* others */
+ strcpy(t_buffer, "u0000 ");
- for (i = 0; i < 4 && (charvalue = s->vf_values[i]) > 0; ++i) {
- if (charvalue <= 0xff) {
- sprintf(cp, "%c0x%02x ", (i ? '+' : ' '), charvalue);
+ } else {
+ unsigned i;
+ for (i = 0; i < 4 && (charvalue = s->vf_values[i]) > 0; ++i) {
+ if (charvalue <= 0xff) {
+ sprintf(t_buffer, "%c0x%02x ", (i ? '+' : ' '), charvalue);
- } else if (charvalue <= 0xffff) {
- sprintf(cp, "%cu%04x ", (i ? '+' : ' '), charvalue);
+ } else if (charvalue <= 0xffff) {
+ sprintf(t_buffer, "%cu%04x ", (i ? '+' : ' '), charvalue);
- } else {
- sprintf(cp, "%cU%06x ", (i ? '+' : ' '), charvalue);
+ } else {
+ sprintf(t_buffer, "%cU%06x ", (i ? '+' : ' '), charvalue);
+ }
}
- cp += strlen(cp);
}
}
- return cp + strlen(cp);
+
+ return ef_buffer(cp, t_buffer, s);
}
@@ -2792,12 +2925,13 @@ ef_charvalue(char *cp, struct _estate *s)
*
* Parameters:
* cp - Echo-line buffer cursor.
+ * s - Edit state.
*
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_virtual(char *cp, struct _estate *s)
+static WChar_t *
+ef_virtual(WChar_t *cp, struct _estate *s)
{
int status;
@@ -2823,12 +2957,13 @@ ef_virtual(char *cp, struct _estate *s)
*
* Parameters:
* cp - Echo-line buffer cursor.
+ * s - Edit state.
*
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_imode(char *cp, const struct _estate *s)
+static WChar_t *
+ef_imode(WChar_t *cp, const struct _estate *s)
{
__CUNUSED(s)
if (buf_imode(curbp)) {
@@ -2848,19 +2983,20 @@ ef_imode(char *cp, const struct _estate *s)
*
* Parameters:
* cp - Echo-line buffer cursor.
- * s - Edit status.
+ * s - Edit state.
*
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_numlines(char *cp, const struct _estate *s)
+static WChar_t *
+ef_numlines(WChar_t *cp, const struct _estate *s)
{
const int numlines = (int)(curbp ? curbp->b_numlines : 1);
+ char t_buffer[32];
__CUNUSED(s)
- sprintf(cp, numlines > 9999 ? "%u" : "%-4u", numlines);
- return cp + strlen(cp);
+ sprintf(t_buffer, numlines > 9999 ? "%u" : "%-4u", numlines);
+ return ef_buffer(cp, t_buffer, s);
}
@@ -2869,21 +3005,20 @@ ef_numlines(char *cp, const struct _estate *s)
*
* Parameters:
* cp - Echo-line buffer cursor.
- * s - Edit status.
+ * s - Edit state.
*
* Returns:
* resulting buffer cursor
*/
-static char *
-ef_filemode(char *cp, const struct _estate *s)
+static WChar_t *
+ef_filemode(WChar_t *cp, const struct _estate *s)
{
int mode = (curbp ? curbp->b_mode : 0);
- char buffer[16];
+ char t_buffer[16];
__CUNUSED(s)
- file_modedesc((mode_t)mode, NULL, 0, buffer, sizeof(buffer));
- strcpy(cp, (const char *)buffer);
- return cp + strlen(cp);
+ file_modedesc((mode_t)mode, NULL, 0, t_buffer, sizeof(t_buffer));
+ return ef_buffer(cp, t_buffer, s);
}
@@ -2892,16 +3027,17 @@ ef_filemode(char *cp, const struct _estate *s)
*
* Parameters:
* cp - Echo-line buffer cursor.
- * s - Edit status.
+ * s - Edit state.
*
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_line(char *cp, const struct _estate *s)
+static WChar_t *
+ef_line(WChar_t *cp, const struct _estate *s)
{
- sprintf(cp, s->bf_line > 9999 ? "Line:%-5u" : "Line: %-4u", s->bf_line);
- return cp + strlen(cp);
+ char t_buffer[32];
+ sprintf(t_buffer, s->bf_line > 9999 ? "Line:%-5u" : "Line: %-4u", s->bf_line);
+ return ef_buffer(cp, t_buffer, s);
}
@@ -2910,16 +3046,17 @@ ef_line(char *cp, const struct _estate *s)
*
* Parameters:
* cp - Echo-line buffer cursor.
- * s - Edit status.
+ * s - Edit state.
*
* Returns:
* resulting buffer cursor
*/
-static char *
-ef_col(char *cp, const struct _estate *s)
+static WChar_t *
+ef_col(WChar_t *cp, const struct _estate *s)
{
- sprintf(cp, s->bf_col > 99 ? "Col:%-3u" : "Col: %-2u", s->bf_col);
- return cp + strlen(cp);
+ char t_buffer[32];
+ sprintf(t_buffer, s->bf_col > 99 ? "Col:%-3u" : "Col: %-2u", s->bf_col);
+ return ef_buffer(cp, t_buffer, s);
}
@@ -2928,26 +3065,24 @@ ef_col(char *cp, const struct _estate *s)
*
* Parameters:
* cp - Echo-line buffer cursor.
- * s - Edit status.
+ * s - Edit state.
*
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_percent(char *cp, const struct _estate *s)
+static WChar_t *
+ef_percent(WChar_t *cp, const struct _estate *s)
{
+ char t_buffer[32];
accint_t perc;
perc = ((accint_t)s->bf_line * 100) / (accint_t)(curbp && curbp->b_numlines > 0 ? curbp->b_numlines : 1);
- if (perc > 100) {
- perc = 100;
- }
if (perc >= 100) {
- strcpy(cp, "END");
+ strcpy(t_buffer, "END");
} else {
- sprintf(cp, "%2lu%%", perc);
+ sprintf(t_buffer, "%2lu%%", perc);
}
- return cp + strlen(cp);
+ return ef_buffer(cp, t_buffer, s);
}
@@ -2956,23 +3091,24 @@ ef_percent(char *cp, const struct _estate *s)
*
* Parameters:
* cp - Echo-line buffer cursor.
- * s - Edit status.
- *
+ * s - Edit state.
+ *
* Returns:
- * resulting buffer cursor
+ * resulting buffer cursor.
*/
-static char *
-ef_time(char *cp, const struct _estate *s, int hour24)
+static WChar_t *
+ef_time(WChar_t *cp, int hour24, const struct _estate *s)
{
- if (hour24) {
- sprintf(cp, "%02d:%02d", s->tm_hour, s->tm_min);
+ char t_buffer[32];
+ if (hour24) {
+ sprintf(t_buffer, "%02d:%02d", s->tm_hour, s->tm_min);
} else {
- sprintf(cp, "%d:%02d%cm",
+ sprintf(t_buffer, "%d:%02d%cm",
(s->tm_hour > 12 ? s->tm_hour - 12 : (s->tm_hour == 0 ? 12 : s->tm_hour)),
s->tm_min, s->tm_hour >= 12 ? 'p' : 'a');
}
- return cp + strlen(cp);
+ return ef_buffer(cp, t_buffer, s);
}
@@ -2981,15 +3117,15 @@ ef_time(char *cp, const struct _estate *s, int hour24)
*
* Parameters:
* cp - Echo-line buffer cursor.
- * s - Edit status.
+ * s - Edit state.
*
* Returns:
* resulting buffer cursor
*/
-static char *
-ef_date(char *cp, const struct _estate *s, int format)
+static WChar_t *
+ef_date(WChar_t *cp, int format, const struct _estate *s)
{
- char t_month[16];
+ char t_buffer[32], t_month[16];
char delim = '-';
/* 30.. delimiter as '/' */
@@ -3010,32 +3146,32 @@ ef_date(char *cp, const struct _estate *s, int format)
switch (format) {
case 7: /* mm-dd */
- sprintf(cp, "%s%c%02d", t_month, delim, s->tm_day);
+ sprintf(t_buffer, "%s%c%02d", t_month, delim, s->tm_day);
break;
case 6: /* dd-mm[m] */
- sprintf(cp, "%02d%c%s", s->tm_day, delim, t_month);
+ sprintf(t_buffer, "%02d%c%s", s->tm_day, delim, t_month);
break;
case 5: /* mm[m]-dd-yy */
- sprintf(cp, "%s%c%02d%c%02d", t_month, delim, s->tm_day, delim, s->tm_year%100);
+ sprintf(t_buffer, "%s%c%02d%c%02d", t_month, delim, s->tm_day, delim, s->tm_year%100);
break;
case 4: /* dd-mm[m]-yy */
- sprintf(cp, "%02d%c%s%c%02d", s->tm_day, delim, t_month, delim, s->tm_year%100);
+ sprintf(t_buffer, "%02d%c%s%c%02d", s->tm_day, delim, t_month, delim, s->tm_year%100);
break;
case 3: /* mm[m]-dd-yyyy */
- sprintf(cp, "%s%c%02d%c%04d", t_month, delim, s->tm_day, delim, s->tm_year);
+ sprintf(t_buffer, "%s%c%02d%c%04d", t_month, delim, s->tm_day, delim, s->tm_year);
break;
case 2: /* dd-mm[m]-yyyy */
- sprintf(cp, "%02d%c%s%c%04d", s->tm_day, delim, t_month, delim, s->tm_year);
+ sprintf(t_buffer, "%02d%c%s%c%04d", s->tm_day, delim, t_month, delim, s->tm_year);
break;
case 1: /* yy-mm[m]-dd */
- sprintf(cp, "%02d%c%s%c%02d", s->tm_year%100, delim, t_month, delim, s->tm_day);
+ sprintf(t_buffer, "%02d%c%s%c%02d", s->tm_year%100, delim, t_month, delim, s->tm_day);
break;
case 0: /* yyyy-mm[m]-dd */
default:
- sprintf(cp, "%04d%c%s%c%02d", s->tm_year, delim, t_month, delim, s->tm_day);
+ sprintf(t_buffer, "%04d%c%s%c%02d", s->tm_year, delim, t_month, delim, s->tm_day);
break;
}
- return cp + strlen(cp);
+ return ef_buffer(cp, t_buffer, s);
}
@@ -3044,16 +3180,16 @@ ef_date(char *cp, const struct _estate *s, int format)
*
* Parameters:
* cp - Echo-line buffer cursor.
- * s - Edit status.
+ * s - Edit state.
*
* Returns:
* resulting buffer cursor
*/
-static char *
-ef_version(char *cp, const struct _estate *s)
+static WChar_t *
+ef_version(WChar_t *cp, const struct _estate *s)
{
__CUNUSED(s)
- sprintf(cp, "%s", x_version);
- return cp + strlen(cp);
+ return ef_buffer(cp, x_version, s);
}
+
/*end*/
diff --git a/gr/file.c b/gr/file.c
index 95020678..27490dbd 100644
--- a/gr/file.c
+++ b/gr/file.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_file_c,"$Id: file.c,v 1.86 2021/04/18 17:12:41 cvsuser Exp $")
+__CIDENT_RCSID(gr_file_c,"$Id: file.c,v 1.90 2021/10/18 13:19:59 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: file.c,v 1.86 2021/04/18 17:12:41 cvsuser Exp $
+/* $Id: file.c,v 1.90 2021/10/18 13:19:59 cvsuser Exp $
* File-buffer primitives and support.
*
*
@@ -89,7 +89,7 @@ static int buf_trimline(BUFFER_t *bp, const LINECHAR *text, LINENO
static int file_copy(const char *src, const char *dst, mode_t perms, uid_t owner, gid_t group);
static int file_cmp_char(const int c1, const int c2);
-static void file_canonicalize2(const char *fname, char *buf);
+static void file_canonicalize2(const char *filename, char *path, int length);
static size_t varlen(const char *dp, const char *dpend);
static char * varend(char *dp, char *dpend, const int what);
@@ -189,7 +189,7 @@ do_output_file(void) /* ([string filename]) */
/* file image not exist */
if (!BFTST(curbp, BF_SYSBUF) &&
- fileio_access(fname, 0) >= 0) {
+ sys_access(fname, 0) >= 0) {
errorf("Output file '%s' already exists.", fname);
chk_free(fname);
return;
@@ -674,7 +674,7 @@ static int
buf_insert(BUFFER_t *bp, const char *fname, int inserting, const int32_t flags, const char *encoding)
{
const int startup = ((EDIT_STARTUP & flags) ? TRUE : FALSE);
- BUFFER_t *saved_bp = curbp;
+ BUFFER_t *ocurbp = curbp;
int fd, readonly = 0;
#if (TODO_POPEN)
@@ -750,8 +750,7 @@ buf_insert(BUFFER_t *bp, const char *fname, int inserting, const int32_t flags,
BFSET(bp, BF_SYSBUF);
}
- curbp = bp;
- set_hooked();
+ set_curbp(bp);
numlines = buf_readin(bp, fd, fname, sb.st_size, flags, encoding);
vfs_close(fd);
fd = -1;
@@ -778,8 +777,7 @@ buf_insert(BUFFER_t *bp, const char *fname, int inserting, const int32_t flags,
wp->w_status |= WFHARD;
}
- curbp = saved_bp;
- set_hooked();
+ set_curbp(ocurbp);
return (numlines >= 0 ? 0 : -1);
}
}
@@ -833,7 +831,7 @@ buf_diskchanged(BUFFER_t *bp)
struct stat sb;
if (bp->b_fname[0] && bp->b_mtime) { /* was read in */
- if (stat(bp->b_fname, &sb) >= 0) {
+ if (sys_stat(bp->b_fname, &sb) >= 0) {
if (sb.st_mtime > bp->b_mtime) {
if ((size_t)sb.st_size != bp->b_rsize) {
return 2; /* size change */
@@ -961,7 +959,7 @@ file_write(const char *fname, const int32_t flags)
BFCLR(curbp, BF_CHANGED);
BFCLR(curbp, BF_BACKUP);
curbp->b_nummod = 0;
- if (stat(curbp->b_fname, &sb) >= 0) {
+ if (sys_stat(curbp->b_fname, &sb) >= 0) {
curbp->b_mtime = sb.st_mtime; /* on disk time-stamp */
curbp->b_rsize = sb.st_size;
}
@@ -1833,7 +1831,7 @@ buf_writeout(BUFFER_t *bp, const char *fname, int undo, int append /*const char
__CUNUSED(undo)
oflags = OPEN_W_BINARY | O_WRONLY | O_CREAT;
- if (stat(fname, &sb) >= 0) {
+ if (sys_stat(fname, &sb) >= 0) {
bp->b_mode = sb.st_mode; /* update permissions */
} else {
oflags |= O_EXCL;
@@ -1853,7 +1851,7 @@ buf_writeout(BUFFER_t *bp, const char *fname, int undo, int append /*const char
return FALSE;
}
- curbp = bp;
+ set_curbp(bp);
termlen = file_terminator_get(bp, termbuf, sizeof(termbuf), NULL);
infof("Writing ...");
@@ -1931,7 +1929,7 @@ buf_writeout(BUFFER_t *bp, const char *fname, int undo, int append /*const char
errorf("Error closing file: File system may be full.");
}
}
- curbp = saved_bp;
+ set_curbp(saved_bp);
return TRUE;
error:;
@@ -1954,7 +1952,7 @@ error:;
} else {
vfs_fclose(fp);
}
- curbp = saved_bp;
+ set_curbp(saved_bp);
return FALSE;
}
@@ -2193,7 +2191,7 @@ do_edit_file(int version) /* int ([int mode], [string | list file ...]) */
char path[MAX_PATH];
if (NULL == get_xarg(fileidx, "Edit file: ", path, sizeof(path))) {
- if (xf_readonly || -1 == fileio_access(curbp->b_fname, W_OK)) {
+ if (xf_readonly || -1 == sys_access(curbp->b_fname, W_OK)) {
BFSET(curbp, BF_RDONLY);
} else {
BFCLR(curbp, BF_RDONLY);
@@ -2718,8 +2716,7 @@ file_load(const char *fname, const int32_t flags, const char *encoding)
if (0 == (EDIT_AGAIN & flags) && BFTST(bp, BF_READ)) {
trace_log("=> already(2)\n");
- curbp = bp; /* already read */
- set_hooked();
+ set_curbp(bp); /* already read */
ret = 2;
} else {
@@ -2769,9 +2766,7 @@ file_load(const char *fname, const int32_t flags, const char *encoding)
buf_type_default(bp);
}
}
-
- curbp = bp;
- set_hooked();
+ set_curbp(bp);
lrenumber(bp);
if (!noundo) {
@@ -3061,7 +3056,7 @@ buf_rollbackups(BUFFER_t *bp, const char *path, int remove_flag)
trace_log("\tVERSION=%d\n", bversion);
if (bversion <= 1) {
if (remove_flag) {
- fileio_unlink(path);
+ sys_unlink(path);
}
return;
}
@@ -3088,14 +3083,14 @@ buf_rollbackups(BUFFER_t *bp, const char *path, int remove_flag)
}
/* $BACKUP// */
sprintf(nname + dirlen, "%c%d%c%s", PATH_SEPERATOR, bversion + 1, PATH_SEPERATOR, filename);
- fileio_unlink(nname);
+ sys_unlink(nname);
- if (0 == fileio_access(oname, F_OK)) {
+ if (0 == sys_access(oname, F_OK)) {
if (rename(oname, nname) < 0) {
char *tcp = strrchr(nname, PATH_SEPERATOR);
*tcp = 0;
- (void) fileio_mkdir(nname, 0777 & ~x_umask);
+ sys_mkdir(nname, 0777 & ~x_umask);
*tcp = PATH_SEPERATOR;
if (-1 == rename(oname, nname)) {
eeprintx("unable to rename '%s' to '%s'", oname, nname);
@@ -3213,16 +3208,16 @@ buf_backup(BUFFER_t *bp)
#if defined(HAVE_LINK)
#if defined(HAVE_LSTAT)
/* Let's look at the *real* entry and see if it is a symbolic link. */
- r = lstat(fname, &sb);
+ r = sys_lstat(fname, &sb);
if (r == 0 && (sb.st_mode & S_IFLNK)) {
- stat(fname, &sb);
+ sys_stat(fname, &sb);
sb.st_nlink = 1 + 1; /* force backup via copy method */
} else if (r < 0) {
sb.st_nlink = 1 + 1;
}
#else
- r = stat(fname, &sb)
+ r = sys_stat(fname, &sb)
if (r < 0) {
sb.st_nlink = 1 + 1;
}
@@ -3419,11 +3414,11 @@ file_copy(
if ((ifd = fileio_open(src, OPEN_R_BINARY | O_RDONLY, 0)) < 0) {
fileio_close(ofd);
- fileio_unlink(dst);
+ sys_unlink(dst);
return TRUE;
}
- (void) fileio_chmod(dst, perms); /* FIXME: return */
+ (void) sys_chmod(dst, perms); /* FIXME: return */
#ifdef HAVE_CHOWN
if (-1 == chown(dst, owner, group))
ewprintf("warning: unable to chown(%s)", dst);
@@ -4140,18 +4135,21 @@ file_cwdd(int drv, char *cwdd, unsigned length)
char *
file_canonicalize(const char *filename, char *path, int length)
{
- if (path && filename != path && length >= MAX_PATH) {
- file_canonicalize2(filename, path); /* normal case, correctly sized buffer */
+ assert(filename);
+
+ if (path && length >= MAX_PATH) { /* explicit buffer */
+ file_canonicalize2(filename, path, length);
return path;
} else {
- char t_path[MAX_PATH];
+ char t_path[MAX_PATH] = {0};
- file_canonicalize2(filename, t_path);
- if (path && length > 0) { /* local result */
+ file_canonicalize2(filename, t_path, sizeof(t_path));
+ if (path && length > 0) { /* local result; may truncate/FIXME */
strxcpy(path, (const char *)t_path, length);
return path;
}
+
return chk_salloc(t_path); /* dynamic */
}
/*NOTREACHED*/
@@ -4159,22 +4157,15 @@ file_canonicalize(const char *filename, char *path, int length)
static void
-file_canonicalize2(const char *filename, char *path)
+file_canonicalize2(const char *filename, char *path, int length)
{
- char t_filename[MAX_PATH];
- int unc = FALSE, len;
- char *p, *s;
-
- strxcpy(t_filename, filename, sizeof(t_filename));
- filename = t_filename; /* working copy */
-
#if defined(_VMS)
if (strchr(filename, PATH_SEPERATOR) != NULL) {
- filename = sys_fname_unix_to_vms(filename, path, sizeof(t_filename));
+ filename = sys_fname_unix_to_vms(filename, path, length);
}
if (filename != path) {
- strxcpy(path, (const char *)filename, sizeof(t_filename));
+ strxcpy(path, (const char *)filename, length);
}
if (strchr(path, ':') == NULL) {
@@ -4183,9 +4174,18 @@ file_canonicalize2(const char *filename, char *path)
#else /*!VMS*/
+ const int filenamelen = strlen(filename) + 1 /*nul*/;
+ char *t_filename = alloca(filenamelen);
+ int unc = FALSE, len;
+ char *p, *s;
+
+ assert(length >= MAX_PATH);
+
+ memcpy(t_filename, filename, filenamelen); /* copy, allow emplace */
#if defined(DOSISH) /* normalize */
file_slashes(t_filename);
#endif
+ filename = t_filename;
/* preserve UNC paths (//servername/...) */
if (PATH_SEPERATOR == filename[0] && PATH_SEPERATOR == filename[1]) {
@@ -4196,10 +4196,11 @@ file_canonicalize2(const char *filename, char *path)
}
if (*cursor && cursor > filename + 2) { /* trailing separator */
- while (filename < cursor) {
+ while (length && filename < cursor) {
*path++ = *filename++;
+ --length;
}
- strcpy(path, filename);
+ strxcpy(path, filename, length);
unc = TRUE;
}
}
@@ -4218,8 +4219,10 @@ file_canonicalize2(const char *filename, char *path)
drv = cwd[0];
cwd += 2;
}
+
} else {
cwd = file_cwd(NULL, 0);
+
if (isalpha(*((unsigned char *)cwd)) && ':' == cwd[1]) {
drv = cwd[0];
cwd += 2;
@@ -4227,28 +4230,36 @@ file_canonicalize2(const char *filename, char *path)
} else if (PATH_SEPERATOR == cwd[0] && PATH_SEPERATOR == cwd[1]) {
*path++ = *cwd++;
*path++ = *cwd++;
- while (*cwd && PATH_SEPERATOR != *cwd) {
+ length -= 2;
+
+ while (length && *cwd && PATH_SEPERATOR != *cwd) {
*path++ = *cwd++; /* preserve UNC */
+ --length;
}
unc = TRUE;
}
}
+
if (drv > 0) { /* assign and preserve drive */
*path++ = drv;
*path++ = ':';
+ length -= 2;
}
#endif /*DOSISH*/
if (PATH_SEPERATOR == *filename) { /* absolute */
- strcpy(path, filename);
+ strxcpy(path, filename, length);
+
} else {
if (NULL == cwd) cwd = file_cwd(NULL, 0);
if (PATH_SEPERATOR == cwd[0] && 0 == cwd[1]) {
/* / */
- sprintf(path, "%c%s", PATH_SEPERATOR, filename);
+ len = snprintf(path, length, "%c%s", PATH_SEPERATOR, filename);
} else { /* */
- sprintf(path, "%s%c%s", cwd, PATH_SEPERATOR, filename);
+ len = snprintf(path, length, "%s%c%s", cwd, PATH_SEPERATOR, filename);
}
+ if (len < 0 || len >= length)
+ path[length - 1] = 0; /* overflow/FIXME */
}
}
@@ -4294,6 +4305,7 @@ file_canonicalize2(const char *filename, char *path)
if ((len = (int)strlen(path)) < 2) {
return;
}
+ assert(len < length);
if (PATH_SEPERATOR == path[len - 1]) { /* XXX/ -> XXX */
path[len - 1] = 0;
@@ -4354,4 +4366,5 @@ file_canonicalize2(const char *filename, char *path)
}
#endif /*! _VMS*/
}
+
/*end*/
diff --git a/gr/getkey.c b/gr/getkey.c
index 303e5a2a..021967cd 100644
--- a/gr/getkey.c
+++ b/gr/getkey.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_getkey_c,"$Id: getkey.c,v 1.44 2015/02/11 23:25:13 cvsuser Exp $")
+__CIDENT_RCSID(gr_getkey_c,"$Id: getkey.c,v 1.46 2021/10/15 08:58:07 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: getkey.c,v 1.44 2015/02/11 23:25:13 cvsuser Exp $
+/* $Id: getkey.c,v 1.46 2021/10/15 08:58:07 cvsuser Exp $
* Low level input, both keyboard and mouse.
*
*
@@ -299,8 +299,8 @@ io_wait(int state, struct IOEvent *evt, accint_t utmo)
assert(EVT_NONE != evt->type);
return 0;
}
- Sleep(250);
- } while ((tmo -= 250) > 0);
+ Sleep(50);
+ } while ((tmo -= 50) > 0);
return event;
}
#endif /*CYGWIN*/
@@ -1544,5 +1544,3 @@ io_device_pollfds(int *count)
#endif /*HAVE_POLL*/
/*end*/
-
-
diff --git a/gr/keyboard.c b/gr/keyboard.c
index 9d46e968..16e146ec 100644
--- a/gr/keyboard.c
+++ b/gr/keyboard.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_keyboard_c,"$Id: keyboard.c,v 1.62 2020/05/03 18:25:44 cvsuser Exp $")
+__CIDENT_RCSID(gr_keyboard_c,"$Id: keyboard.c,v 1.66 2021/07/18 23:03:19 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: keyboard.c,v 1.62 2020/05/03 18:25:44 cvsuser Exp $
+/* $Id: keyboard.c,v 1.66 2021/07/18 23:03:19 cvsuser Exp $
* Manipulate key maps and bindings.
*
*
@@ -79,6 +79,8 @@ typedef struct _keyboard {
int kt_pushed; /* push state. */
} keyboard_t;
+#define IS_UNICODE(x) (IS_CHARACTER(x) && x > 0xff)
+
#define HIST_DEPTH 16 /* AUTOCONF - configuration item. */
#define HIST_NAME 64 /* AUTOCONF */
@@ -125,27 +127,27 @@ static char * historyget(int idx);
* internal codes labels
*/
static const char * keypad_names[] = {
- "Ins", /* 0 */
- "End", /* 1 */
- "Down", /* 2 */
- "PgDn", /* 3 */
- "Left", /* 4 */
- "5", /* 5 */
- "Right", /* 6 */
- "Home", /* 7 */
- "Up", /* 8 */
- "PgUp", /* 9 */
- "Del", /* 10 Delete */
- "Plus", /* 11 + */
- "Minus", /* 12 - */
- "Star", /* 13 * */
- "Divide", /* 14 / */
- "Equals", /* 15 = */
- "Enter", /* 16 */
- "Pause", /* 17 */
- "PrtSc", /* 18 */
- "Scroll", /* 19 */
- "NumLock" /* 20 */
+ "Ins", /* KEYPAD_0 - 0 */
+ "End", /* KEYPAD_1 - 1 */
+ "Down", /* KEYPAD_2 - 2 */
+ "PgDn", /* KEYPAD_3 - 3 */
+ "Left", /* KEYPAD_4 - 4 */
+ "5", /* KEYPAD_5 - 5 */
+ "Right", /* KEYPAD_6 - 6 */
+ "Home", /* KEYPAD_7 - 7 */
+ "Up", /* KEYPAD_8 - 8 */
+ "PgUp", /* KEYPAD_9 - 9 */
+ "Del", /* KEYPAD_DEL - 10 Delete */
+ "Plus", /* KEYPAD_PLUS - 11 + */
+ "Minus", /* KEYPAD_MINUS - 12 - */
+ "Star", /* KEYPAD_STAR - 13 * */
+ "Divide", /* KEYPAD_DIV - 14 / */
+ "Equals", /* KEYPAD_EQUAL - 15 = */
+ "Enter", /* KEYPAD_ENTER - 16 */
+ "Pause", /* KEYPAD_PAUSE - 17 */
+ "PrtSc", /* KEYPAD_PRTSC - 18 */
+ "Scroll", /* KEYPAD_SCROLL - 19 */
+ "NumLock" /* KEYPAD_NUMLOCK - 20 */
};
struct map {
@@ -209,6 +211,7 @@ static const struct map keystring_tbl[] = {
{ 4, "OPEN", RANGE_MISC, KEY_OPEN },
{ 4, "SAVE", RANGE_MISC, KEY_SAVE },
{ 4, "MENU", RANGE_MISC, KEY_MENU },
+ { 5, "BREAK", RANGE_MISC, KEY_BREAK },
{ 0, NULL, 0, 0}
};
@@ -224,88 +227,128 @@ static const struct map keystring_tbl[] = {
*/
static const struct w32key {
WORD vk; /* windows virtual key code */
- int mods; /* modifiers */
-#define MOD_ALL -1
-#define MOD_ENHANCED -2
+ int32_t mods; /* modifiers */
+#define VKMOD_ANY -1
+#define VKMOD_ENHANCED -2
+#define VKMOD_NONENHANCED -3
+#define VKMOD_NONSHIFT -4
const char * desc; /* description */
KEY code; /* interval key value */
} w32Keys[] = {
- { VK_BACK, 0, "Back", KEY_BACKSPACE },
- { VK_TAB, 0, "TAB", KEY_TAB },
- { VK_BACK, MOD_SHIFT, "S-Back", SHIFT_BACKSPACE },
- { VK_TAB, MOD_SHIFT, "S-TAB", BACK_TAB },
- { VK_BACK, MOD_CTRL, "C-Back", CTRL_BACKSPACE },
- { VK_TAB, MOD_CTRL, "C-TAB", CTRL_TAB },
- { VK_BACK, MOD_META, "A-Back", ALT_BACKSPACE },
- { VK_TAB, MOD_META, "A-TAB", ALT_TAB },
- { VK_ESCAPE, MOD_ALL, "ESC", KEY_ESC },
- { VK_RETURN, MOD_ALL, "Return", KEY_ENTER },
- { VK_RETURN, MOD_ENHANCED, "Return", KEYPAD_ENTER },
- { VK_PAUSE, MOD_ALL, "Pause", KEYPAD_PAUSE },
- { VK_PRIOR, MOD_ALL, "PRIOR", KEY_PAGEUP },
- { VK_NEXT, MOD_ALL, "NEXT", KEY_PAGEDOWN },
- { VK_END, MOD_ALL, "END", KEY_END },
- { VK_HOME, MOD_ALL, "HOME", KEY_HOME },
- { VK_LEFT, MOD_ALL, "LEFT", KEY_LEFT },
- { VK_UP, MOD_ALL, "UP", KEY_UP },
- { VK_RIGHT, MOD_ALL, "RIGHT", KEY_RIGHT },
- { VK_DOWN, MOD_ALL, "DOWN", KEY_DOWN },
- { VK_INSERT, MOD_ALL, "INSERT", KEY_INS },
- { VK_DELETE, MOD_ALL, "DELETE", KEY_DEL },
- { VK_HELP, MOD_ALL, "HELP", KEY_HELP },
-
- /*
- * XXX - others?
-
- { VK_POUND/0x9C MOD_ALL, "POUND", KEY_POUND },
-
- */
-
- /* VK_NUMPAD1 thru VK_NUMPAD0 are ignored allowing user selection via the NumLock */
-
- { VK_SUBTRACT, MOD_ALL, "-", KEYPAD_MINUS },
- { VK_MULTIPLY, MOD_ALL, "*", KEYPAD_STAR },
- { VK_ADD, MOD_ALL, "+", KEYPAD_PLUS },
- { VK_DIVIDE, MOD_ALL, "/", KEYPAD_DIV },
+ // Only reportsd as an up event, down redirected to event handler.
+// { VK_CANCEL, MOD_CTRL, "Ctrl-Break", KEY_BREAK },
+
+// { VK_KANA, "IME Kana mode", 0 },
+// { VK_HANGUL, "IME Hangul mode", 0 },
+// { VK_IME_ON, "IME On", 0 },
+// { VK_JUNJA, "IME Junja mode", 0 },
+// { VK_FINAL, "IME final mode", 0 },
+// { VK_HANJA, "IME Hanja mode", 0 },
+// { VK_KANJI, "IME Kanji mode", 0 },
+// { VK_IME_OFF, "IME Off", 0 },
+// { VK_CONVERT, "IME convert", 0 },
+// { VK_NONCONVERT, "IME nonconvert", 0 },
+// { VK_ACCEPT, "IME accept", 0 },
+// { VK_MODECHANGE, "IME mode change", 0 },
+
+ { VK_BACK, 0, "Back", KEY_BACKSPACE },
+ { VK_TAB, 0, "Tab", KEY_TAB },
+ { VK_BACK, MOD_SHIFT, "Shift-Back", SHIFT_BACKSPACE },
+ { VK_TAB, MOD_SHIFT, "Shift-Tab", BACK_TAB },
+ { VK_BACK, MOD_CTRL, "Ctrl-Back", CTRL_BACKSPACE },
+ { VK_TAB, MOD_CTRL, "Ctrl-Tab", CTRL_TAB },
+ { VK_BACK, MOD_META, "Alt-Back", ALT_BACKSPACE },
+ { VK_TAB, MOD_META, "Alt-Tab", ALT_TAB },
+ { VK_ESCAPE, VKMOD_ANY, "Esc", KEY_ESC },
+ { VK_RETURN, VKMOD_ANY, "Return", KEY_ENTER },
+ { VK_RETURN, VKMOD_ENHANCED, "Return", KEYPAD_ENTER },
+ { VK_PAUSE, VKMOD_ANY, "Pause", KEYPAD_PAUSE },
+ { VK_PRIOR, VKMOD_ANY, "Prior", KEY_PAGEUP },
+ { VK_NEXT, VKMOD_ANY, "Next", KEY_PAGEDOWN },
+ { VK_END, VKMOD_ANY, "End", KEY_END },
+ { VK_HOME, VKMOD_ANY, "Home", KEY_HOME },
+ { VK_LEFT, VKMOD_ANY, "Left", KEY_LEFT },
+ { VK_UP, VKMOD_ANY, "Uo", KEY_UP },
+ { VK_RIGHT, VKMOD_ANY, "Right", KEY_RIGHT },
+ { VK_DOWN, VKMOD_ANY, "Down", KEY_DOWN },
+ { VK_INSERT, VKMOD_ANY, "Insert", KEY_INS },
+ { VK_DELETE, VKMOD_ANY, "Delete", KEY_DEL },
+ { VK_HELP, VKMOD_ANY, "Help", KEY_HELP },
+
+ /* VK_NUMPAD1 thru VK_NUMPAD0 are ignored allowing user selection via the NumLock */
+
+// { VK_PRIOR, VKMOD_NONENHANCED, "Keypad-PgUp", KEYPAD_PAGEUP },
+// { VK_NEXT, VKMOD_NONENHANCED, "Keypad-PgDn", KEYPAD_PAGEDOWN },
+// { VK_END, VKMOD_NONENHANCED, "Keypad-End", KEYPAD_END },
+// { VK_HOME, VKMOD_NONENHANCED, "Keypad-Home", KEYPAD_HOME },
+// { VK_LEFT, VKMOD_NONENHANCED, "Keypad-Left", KEYPAD_LEFT },
+// { VK_CLEAR, VKMOD_NONENHANCED, "Keypad-5", KEYPAD_5 },
+// { VK_UP, VKMOD_NONENHANCED, "Keypad-Up", KEYPAD_UP },
+// { VK_RIGHT, VKMOD_NONENHANCED, "Keypad-Right", KEYPAD_RIGHT },
+// { VK_DOWN, VKMOD_NONENHANCED, "Keypad-Down", KEYPAD_DOWN },
+// { VK_INSERT, VKMOD_NONENHANCED, "Keypad-Ins", KEYPAD_INS },
+// { VK_DELETE, VKMOD_NONENHANCED, "Keypad-Delete", KEYPAD_DEL },
+ { VK_SUBTRACT, VKMOD_ANY, "Keypad-Minus", KEYPAD_MINUS },
+ { VK_MULTIPLY, VKMOD_ANY, "Keypad-Star", KEYPAD_STAR },
+ { VK_ADD, VKMOD_ANY, "Keypad-Plus", KEYPAD_PLUS },
+ { VK_DIVIDE, VKMOD_ANY, "Keypad-Divide", KEYPAD_DIV },
/* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
- { 0x30, MOD_CTRL, "0", CTRL_0 },
- { 0x31, MOD_CTRL, "1", CTRL_1 },
- { 0x32, MOD_CTRL, "2", CTRL_2 },
- { 0x33, MOD_CTRL, "3", CTRL_3 },
- { 0x34, MOD_CTRL, "4", CTRL_4 },
- { 0x35, MOD_CTRL, "5", CTRL_5 },
- { 0x36, MOD_CTRL, "6", CTRL_6 },
- { 0x37, MOD_CTRL, "7", CTRL_7 },
- { 0x38, MOD_CTRL, "8", CTRL_8 },
- { 0x39, MOD_CTRL, "9", CTRL_9 },
-
- { VK_F1, MOD_ALL, "F1", F(1) },
- { VK_F2, MOD_ALL, "F2", F(2) },
- { VK_F3, MOD_ALL, "F3", F(3) },
- { VK_F4, MOD_ALL, "F4", F(4) },
- { VK_F5, MOD_ALL, "F5", F(5) },
- { VK_F6, MOD_ALL, "F6", F(6) },
- { VK_F7, MOD_ALL, "F7", F(7) },
- { VK_F8, MOD_ALL, "F8", F(8) },
- { VK_F9, MOD_ALL, "F9", F(9) },
- { VK_F10, MOD_ALL, "F10", F(10) },
- { VK_F11, MOD_ALL, "F11", F(11) },
- { VK_F12, MOD_ALL, "F12", F(12) },
- { VK_F13, MOD_ALL, "F13", F(13) },
- { VK_F14, MOD_ALL, "F14", F(14) },
- { VK_F15, MOD_ALL, "F15", F(15) },
- { VK_F16, MOD_ALL, "F16", F(16) },
- { VK_F17, MOD_ALL, "F17", F(17) },
- { VK_F18, MOD_ALL, "F18", F(18) },
- { VK_F19, MOD_ALL, "F19", F(19) },
- { VK_F20, MOD_ALL, "F20", F(20) },
-
- { VK_NUMLOCK, MOD_ALL, "Numlock", KEYPAD_NUMLOCK },
- { VK_SCROLL, MOD_ALL, "Scroll", KEYPAD_SCROLL }
+ { 0x30, MOD_CTRL, "0", CTRL_0 },
+ { 0x31, MOD_CTRL, "1", CTRL_1 },
+ { 0x32, MOD_CTRL, "2", CTRL_2 },
+ { 0x33, MOD_CTRL, "3", CTRL_3 },
+ { 0x34, MOD_CTRL, "4", CTRL_4 },
+ { 0x35, MOD_CTRL, "5", CTRL_5 },
+ { 0x36, MOD_CTRL, "6", CTRL_6 },
+ { 0x37, MOD_CTRL, "7", CTRL_7 },
+ { 0x38, MOD_CTRL, "8", CTRL_8 },
+ { 0x39, MOD_CTRL, "9", CTRL_9 },
+
+ /* VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A) */
+
+ { VK_F1, VKMOD_ANY, "F1", F(1) },
+ { VK_F2, VKMOD_ANY, "F2", F(2) },
+ { VK_F3, VKMOD_ANY, "F3", F(3) },
+ { VK_F4, VKMOD_ANY, "F4", F(4) },
+ { VK_F5, VKMOD_ANY, "F5", F(5) },
+ { VK_F6, VKMOD_ANY, "F6", F(6) },
+ { VK_F7, VKMOD_ANY, "F7", F(7) },
+ { VK_F8, VKMOD_ANY, "F8", F(8) },
+ { VK_F9, VKMOD_ANY, "F9", F(9) },
+ { VK_F10, VKMOD_ANY, "F10", F(10) },
+ { VK_F11, VKMOD_ANY, "F11", F(11) },
+ { VK_F12, VKMOD_ANY, "F12", F(12) },
+ { VK_F13, VKMOD_ANY, "F13", F(13) },
+ { VK_F14, VKMOD_ANY, "F14", F(14) },
+ { VK_F15, VKMOD_ANY, "F15", F(15) },
+ { VK_F16, VKMOD_ANY, "F16", F(16) },
+ { VK_F17, VKMOD_ANY, "F17", F(17) },
+ { VK_F18, VKMOD_ANY, "F18", F(18) },
+ { VK_F19, VKMOD_ANY, "F19", F(19) },
+ { VK_F20, VKMOD_ANY, "F20", F(20) },
+
+ { VK_NUMLOCK, VKMOD_ANY, "Numlock", KEYPAD_NUMLOCK },
+ { VK_SCROLL, VKMOD_ANY, "Scroll", KEYPAD_SCROLL },
+
+// { VK_OEM_1, // ';:' for US
+// { VK_OEM_PLUS, VKMOD_NONSHIFT, "+" '+' },
+// { VK_OEM_COMMA, VKMOD_NONSHIFT, "," ',' },
+// { VK_OEM_MINUS, VKMOD_NONSHIFT, "-" '-' },
+// { VK_OEM_PERIOD, VKMOD_NONSHIFT, "." '.' },
+// { VK_OEM_2, // '/?' for US
+// { VK_OEM_3, VKMOD_NONSHIFT, "~", '~' },
+// { VK_OEM_4, // '[{' for US
+// { VK_OEM_5, // '\|' for US
+// { VK_OEM_6, // ']}' for US
+// { VK_OEM_7, // ''"' for US
+
+ { VK_OEM_NEC_EQUAL, VKMOD_ANY, "Keypad-Equal", KEYPAD_EQUAL },
+ { VK_ICO_HELP, VKMOD_ANY, "Help", KEY_HELP },
+
};
#endif /*WIN32 || __CYGWIN__*/
@@ -324,6 +367,30 @@ key_init(void)
{
unsigned i;
+ assert((KEY_MASK & (RANGE_MASK | MOD_MASK)) == 0);
+ assert((RANGE_MASK & (KEY_MASK | MOD_MASK)) == 0);
+ assert((MOD_MASK & (KEY_MASK | RANGE_MASK)) == 0);
+
+ assert((RANGE_CHARACTER & ~RANGE_MASK) == 0);
+ assert((RANGE_KEYPAD & ~RANGE_MASK) == 0 && (RANGE_KEYPAD & RANGE_MASK));
+ assert((RANGE_MISC & ~RANGE_MASK) == 0 && (RANGE_MISC & RANGE_MASK));
+ assert((RANGE_MULTIKEY & ~RANGE_MASK) == 0 && (RANGE_MULTIKEY & RANGE_MASK));
+ assert((RANGE_PRIVATE & ~RANGE_MASK) == 0 && (RANGE_PRIVATE & RANGE_MASK));
+ assert((RANGE_BUTTON & ~RANGE_MASK) == 0 && (RANGE_BUTTON & RANGE_MASK));
+ assert((RANGE_MASK & ~RANGE_MASK) == 0 && (RANGE_MASK & RANGE_MASK));
+ assert((RANGE_MAX & ~RANGE_MASK) == 0 && (RANGE_MAX & RANGE_MASK));
+
+ assert((MOD_SHIFT & ~MOD_MASK) == 0 && (MOD_SHIFT & MOD_MASK));
+ assert((MOD_CTRL & ~MOD_MASK) == 0 && (MOD_CTRL & MOD_MASK));
+ assert((MOD_META & ~MOD_MASK) == 0 && (MOD_META & MOD_MASK));
+ assert((MOD_APP & ~MOD_MASK) == 0 && (MOD_APP & MOD_MASK));
+
+ assert(IS_CHARACTER(' '));
+ assert(IS_CHARACTER(0x1ff));
+ assert(IS_FUNCTION(F(1)));
+ assert(IS_BUTTON(BUTTON1_DOWN));
+ assert(IS_BUTTON(BUTTON_DRAG));
+
TAILQ_INIT(&x_kbdlist);
x_kbdstack = ll_init();
x_kseqtree = spinit();
@@ -388,7 +455,7 @@ key_shutdown(void)
/* Function: key_typeables
- * Initialise typeable key assignments
+ * Enable all typeable key assignments as "self_insert".
*
* Parameters:
* none
@@ -401,9 +468,10 @@ key_typeables(void)
{
unsigned i;
- for (i = 0; i < 256; ++i) { /* 0 .. 25, extended ASCII */
+ for (i = 0; i <= 0xff; ++i) { /* 0 .. 25, extended ASCII */
key_macro_add(i, NULL);
}
+ key_macro_add(KEY_UNICODE, NULL); /* >= 256 x <= KEY_UNICODE */
}
@@ -477,7 +545,7 @@ key_define_key_seq(int key, const char *str)
*/
sp = spblk(sizeof(keyseq_t) + len);
ks = (keyseq_t *) sp->data;
- ks->ks_code = (KEY)key_code;
+ ks->ks_code = (KEY) key_code;
memcpy(ks->ks_buf, str, len + 1);
sp->key = ks->ks_buf;
spenq(sp, x_kseqtree);
@@ -579,12 +647,9 @@ keyboard_free(keyboard_t *kp)
/* Function: keyboard_find
* Keyboard lookup, searchings both the pushed stack or the popped stack.
*
- * If inc_ref is TRUE, then we are creating a new reference to it.
- * Otherwise we're just going to look at it
- *
* Parameters:
* id - Keyboard identifier.
- * incref - Reference count increment.
+ * incref - Reference count increment on success.
*
* Results:
* Keyboard object, otherwise NULL.
@@ -761,19 +826,23 @@ key_macro_find(int key)
if (curbp->b_keyboard) { /* buffer specific */
sep = stype_lookup(curbp->b_keyboard->kt_macros, (stypekey_t) key);
+ if (NULL == sep && IS_UNICODE(key)) {
+ sep = stype_lookup(curbp->b_keyboard->kt_macros, (stypekey_t) KEY_UNICODE);
+ }
}
if (NULL == sep) { /* keyboard */
sep = stype_lookup(x_kbdcur->kt_macros, (stypekey_t) key);
+ if (NULL == sep && IS_UNICODE(key)) {
+ sep = stype_lookup(x_kbdcur->kt_macros, (stypekey_t) KEY_UNICODE);
+ }
}
if (NULL == sep) {
cp = "nothing";
-
} else {
cp = key_macro_value((const object_t *)sep->se_ptr);
}
-
return cp;
}
@@ -938,7 +1007,7 @@ key_name2code(const char *string, int *lenp)
/* function key, F */
if ('F' == *cp && isdigit(cp[1])) {
key = atoi(++cp) - 1;
- flags |= RANGE_FN;
+ flags |= RANGE_FUNCTION;
while (isdigit(*cp)) {
++cp;
}
@@ -1121,7 +1190,7 @@ key_name2code(const char *string, int *lenp)
supported.
#xxx - Substitutes the '#' lead sequence of digits with
- the represent value. For example '#!23' result in
+ the represent value. For example '#123' result in
the key code 123.
^x - The '^' characters treats the following character
@@ -1141,77 +1210,79 @@ key_name2code(const char *string, int *lenp)
For examples review current supplied macro code.
(start table,format=simple)
- |Key |Description |Keypad|Shift|Ctrl |Alt |Meta |
- |ASCII |ASCII key | | x | x | x | x |
+ |Key |Description |Keypad|Shift|Ctrl |Alt |Meta |
+ |ASCII |ASCII key | | x | x | x | x |
- |F1..F12 |Function keys | | x | x | x | x |
+ |F1..F12 |Function keys | | x | x | x | x |
- |PgDn |Page Down | | | | | |
- |PgUp |Page Up | | | | | |
+ |PgDn |Page Down | | | | | |
+ |PgUp |Page Up | | | | | |
- |Left |Cursor Left | x | x | x | x | |
- |Right |Cursor Right | x | x | x | x | |
- |Up |Cursor Up | x | x | x | x | |
- |Down |Cursor Down | x | x | x | x | |
+ |Left |Cursor Left | x | x | x | x | |
+ |Right |Cursor Right | x | x | x | x | |
+ |Up |Cursor Up | x | x | x | x | |
+ |Down |Cursor Down | x | x | x | x | |
- |Tab | | | | | | |
- |Back-Tab |Shifted Tab | | | | | |
- |Backspace | | | | | | |
- |Back | | | | | | |
- |Del |Delete | | | | | |
+ |Tab | | | | | | |
+ |Back-Tab |Shifted Tab | | | | | |
+ |Backspace | | | | | | |
+ |Back | | | | | | |
+ |Del |Delete | | | | | |
- |Enter |Enter/Return Key | x | | | | |
- |Esc |Escape key | | | | | |
- |Space |Space ( ) | | | | | |
+ |Enter |Enter/Return Key | x | | | | |
+ |Esc |Escape key | | | | | |
+ |Space |Space ( ) | | | | | |
- |Home |Cursor Home | x | | | | |
- |End |Cursor End | x | | | | |
+ |Home |Cursor Home | x | | | | |
+ |End |Cursor End | x | | | | |
- |Ins |Insert | x | | | | |
- |Plus |plus (+) | x | | | | |
- |Minus |minus (-) | x | | | | |
- |Star |star (*) | x | | | | |
+ |Ins |Insert | x | | | | |
+ |Plus |Plus (+) | x | | | | |
+ |Minus |Minus (-) | x | | | | |
+ |Star |Multiply (*) | x | | | | |
+ |Divide |Div (/) | x | | | | |
+ |Equals |Equal (=) | x | | | | |
- |Cancel |Cancel Key | | | | | |
- |Command |Command Key | | | | | |
- |Copy |Copy Key | | | | | |
- |Cut |Cut Key | | | | | |
- |Exit |Exit Key | | | | | |
- |Help |Help Key | | | | | |
- |Menu |Menu Key | | | | | |
- |Next |Next Key | | | | | |
- |Open |Open key | | | | | |
- |Paste |Paste key | | | | | |
- |Prev |Prev Key | | | | | |
- |Prtsc |Print-Screen Key | | | | | |
- |Redo |Redo Key | | | | | |
- |Replace |Replace | | | | | |
- |Save |Save | | | | | |
- |Scroll |Scroll | | | | | |
- |Search |Search | | | | | |
- |Undo |Undo | | | | | |
+ |Cancel |Cancel Key | | | | | |
+ |Command |Command Key | | | | | |
+ |Copy |Copy Key | | | | | |
+ |Cut |Cut Key | | | | | |
+ |Exit |Exit Key | | | | | |
+ |Help |Help Key | | | | | |
+ |Menu |Menu Key | | | | | |
+ |Next |Next Key | | | | | |
+ |Open |Open key | | | | | |
+ |Paste |Paste key | | | | | |
+ |Prev |Prev Key | | | | | |
+ |Prtsc |Print-Screen Key | | | | | |
+ |Redo |Redo Key | | | | | |
+ |Replace |Replace | | | | | |
+ |Save |Save | | | | | |
+ |Scroll |Scroll | | | | | |
+ |Search |Search | | | | | |
+ |Undo |Undo | | | | | |
- |Keypad-# |Keypad 0..9 | | x | x | x | x |
+ |Keypad-# |Keypad 0..9 | | x | x | x | x |
- |Grey-# |Aliases for keypad | | | | | |
+ |Grey-# |Aliases for keypad | | | | | |
- |Button# |Button number # | | | | | |
+ |Button# |Button number # | | | | | |
- |Button#-Up | | | | | | |
+ |Button#-Up | | | | | | |
- |Button#-Double | | | | | | |
+ |Button#-Double | | | | | | |
- |Button#-Motion | | | | | | |
+ |Button#-Motion | | | | | | |
- |Button#-Down | | | | | | |
+ |Button#-Down | | | | | | |
- |Private# |Private keys | | | | | |
+ |Private# |Private keys | | | | | |
- |Mouse |Special Mouse Event | | | | | |
+ |Mouse |Special Mouse Event | | | | | |
- |Wheel-Up |Mousewheel up movement | | | | | |
+ |Wheel-Up |Mousewheel up movement| | | | | |
- |wheel-Down |Mousewheel down | | | | | |
+ |wheel-Down |Mousewheel down | | | | | |
movement
(end table)
@@ -1444,8 +1515,7 @@ key_cache_mouse(ref_t *pp, int code, int front, int x, int y, int win, int where
KEY buffer[(sizeof(KEY) + sizeof(struct IOMouse))/2] = {0},
*msg = buffer;
- assert(code > 0 && code < KEY_VOID);
-
+ assert(code > 0 && code <= (MOD_MASK|RANGE_MASK|KEY_MASK) && code != KEY_VOID);
*msg++ = (KEY)code;
if (RANGE_BUTTON == (RANGE_MASK & code)) {
@@ -1495,7 +1565,7 @@ key_cache_pop(ref_t *pp, struct IOEvent *evt)
assert(used >= (int)sizeof(KEY));
code = (int) *msg;
- assert(code > 0 && code < KEY_VOID);
+ assert(code > 0 && code <= (MOD_MASK|RANGE_MASK|KEY_MASK) && code != KEY_VOID);
evt->type = EVT_KEYDOWN;
if (RANGE_BUTTON == (RANGE_MASK & code)) {
@@ -1546,24 +1616,23 @@ key_cache_test(ref_t *pp)
key_to_int(string key, int raw)
Macro Description:
- The 'key_to_int()' primitive converts a mnemonic key string
- to an integer.
+ The 'key_to_int()' primitive converts a mnemonic key string to an integer.
- The following scheme is utilised for encoding internal
- key-codes, allowing for simple conversion of ASCII character
- code to the internal codes and vice-versa.
+ The following scheme is utilised for encoding internal key-codes,
+ allowing for simple conversion of ASCII character code to the internal
+ codes and vice-versa.
Firstly key-codes are divided into several ranges.
(start table)
[Key Code [Range [Description ]
- ! RANGE_ASCII 0x0000..0x0ff ASCII range.
- ! RANGE_FN 0x0100..0x1ff Support for up to 255 function keys.
- ! RANGE_KEYPAD 0x0200..0x2ff Up to 255 keypad keys.
- ! RANGE_MISC 0x0300..0x3ff Miscellaneous.
- ! RANGE_MULTIKEY 0x0400..0x7ff Multi-key stroke.
- ! RANGE_PRIVATE 0x0800..0x8ff Private key definitions for users.
- ! RANGE_BUTTON 0x0900..0x9ff Mouse buttons and movement.
+ ! RANGE_CHARACTER 0x0 ... 1fffff Character ASCII/Unicode range.
+ ! RANGE_FUNCTION 0x02000... Function keys.
+ ! RANGE_KEYPAD 0x03000... Keypad keys.
+ ! RANGE_MISC 0x04000... Miscellaneous.
+ ! RANGE_MULTIKEY 0x05000... Multi-key stroke.
+ ! RANGE_PRIVATE 0x06000... Private key definitions for users.
+ ! RANGE_BUTTON 0x07000... Mouse buttons and movement.
(end table)
These ranges can be OR'ed with one or more of the following
@@ -1572,9 +1641,9 @@ key_cache_test(ref_t *pp)
(start table)
[Modifier [Code [Description ]
- ! MOD_SHIFT 0x1000 Shift'ed.
- ! MOD_CTRL 0x2000 Ctrl.
- ! MOD_META 0x4000 Meta or Alt.
+ ! MOD_SHIFT 0x00200000 Shift'ed.
+ ! MOD_CTRL 0x00400000 Control.
+ ! MOD_META 0x00800000 Meta or Alt.
(end table)
To further simplify key handling, the follow special key
@@ -1582,44 +1651,46 @@ key_cache_test(ref_t *pp)
(start table)
[Key Code [Description ]
- ! CTRL_1 .. CTRL_10
- ! ALT_1 .. ALT_10
- ! CTRL_A .. CTRL_Z
- ! ALT_Z .. ALT_Z
+ ! CTRL_1 .. CTRL_10 Control 1 thru 10.
+ ! ALT_1 .. ALT_10 Alt 1 thru 10.
+ ! CTRL_A .. CTRL_Z Control A thru Z.
+ ! ALT_Z .. ALT_Z Alt A thru Z.
! KEY_BACKSPACE Backspace.
- ! KEY_CANCEL
- ! KEY_CLOSE
+ ! KEY_BREAK Break.
+ ! KEY_CANCEL Cancel key.
+ ! KEY_CLOSE Close key.
! KEY_COMMAND
- ! KEY_COPY
- ! KEY_COPY_CMD
- ! KEY_CUT
+ ! KEY_COPY Copy to clipboard.
+ ! KEY_COPY_CMD
+ ! KEY_CUT Cut to clipboard.
! KEY_CUT_CMD
- ! KEY_DEL
- ! KEY_END
+ ! KEY_DEL Delete, rubout.
+ ! KEY_DOWN Move down, down arrow.
+ ! KEY_END End key.
! KEY_ENTER Enter key.
! KEY_ESC Escape.
! KEY_EXIT
- ! KEY_HELP
- ! KEY_HOME
- ! KEY_INS
- ! KEY_LEFT
- ! KEY_MENU
+ ! KEY_HELP Help, usage.
+ ! KEY_HOME Home key.
+ ! KEY_INS Insert.
+ ! KEY_LEFT Move left, left arrow.
+ ! KEY_MENU Menu key.
! KEY_NEWLINE New line.
- ! KEY_NEXT
- ! KEY_OPEN
- ! KEY_PAGEDOWN
- ! KEY_PAGEUP
- ! KEY_PASTE
- ! KEY_PREV
- ! KEY_REDO
+ ! KEY_NEXT Next.
+ ! KEY_OPEN Open key.
+ ! KEY_PAGEDOWN Page down.
+ ! KEY_PAGEUP Page up.
+ ! KEY_PASTE Paste clipboard.
+ ! KEY_PREV Prior, previous.
+ ! KEY_REDO Redo, again.
! KEY_REPLACE
- ! KEY_RIGHT
+ ! KEY_RIGHT Move right, right arrow.
! KEY_SAVE
- ! KEY_SEARCH
+ ! KEY_SEARCH Search.
! KEY_TAB Tab.
- ! KEY_UNDO
- ! KEY_UNDO_CMD
- ! KEY_UP
+ ! KEY_UNDO Undo key.
+ ! KEY_UNDO_CMD Undo key.
+ ! KEY_UP Move up, up arrow.
! KEY_WDOWN
! KEY_WDOWN2
! KEY_WLEFT
@@ -1764,7 +1835,7 @@ key_code2name(int key)
/*
* parse the user definable 'kbd_labels' list, if defined.
*/
- if (! IS_ASCII(key) &&
+ if (! IS_CHARACTER(key) &&
NULL != (sp = sym_global_lookup("kbd_labels")) && F_LIST == sp->s_type) {
/*
* iterate table, abort on error.
@@ -1806,9 +1877,9 @@ key_code2name(int key)
}
}
- /* normal ASCII case */
+ /* normal character case */
do_normal:
- if (IS_ASCII(key)) {
+ if (IS_CHARACTER(key)) {
key_to_char(buf, key);
assert(strlen(buf) < sizeof(buf));
return buf;
@@ -1831,145 +1902,128 @@ key_code2name(int key)
case MOUSE_KEY:
desc ="Mouse";
break;
-
case BACK_TAB:
desc = "Back-Tab";
break;
-
case CTRL_TAB:
desc = "Ctrl-Tab";
break;
-
case ALT_TAB:
desc = "Alt-Tab";
break;
-
case SHIFT_BACKSPACE:
desc = "Shift-Backspace";
break;
-
case CTRL_BACKSPACE:
desc = "Ctrl-Backspace";
break;
-
case ALT_BACKSPACE:
desc = "Alt-Backspace";
break;
-
case KEY_UNDO_CMD:
case KEY_UNDO:
desc = "Undo";
break;
-
case KEY_COPY_CMD:
case KEY_COPY:
desc = "Copy";
break;
-
case KEY_CUT_CMD:
case KEY_CUT:
desc = "Cut";
break;
-
case KEY_PASTE:
desc = "Paste";
break;
-
case KEY_HELP:
desc = "Help";
break;
-
case KEY_REDO:
desc = "Redo";
break;
-
case KEY_SEARCH:
desc = "Search";
break;
-
case KEY_REPLACE:
desc = "Replace";
break;
-
case KEY_CANCEL:
desc = "Cancel";
break;
-
case KEY_COMMAND:
desc = "Command";
break;
-
case KEY_EXIT:
desc = "Exit";
break;
-
case KEY_NEXT:
desc = "Next";
break;
-
case KEY_PREV:
desc = "Prev";
break;
-
case KEY_OPEN:
desc = "Open";
break;
-
case KEY_SAVE:
desc = "Save";
break;
-
case KEY_MENU:
desc = "Menu";
break;
-
+ case KEY_BREAK:
+ desc = "Break";
+ break;
case WHEEL_UP:
desc = "Wheel-Up";
break;
-
case WHEEL_DOWN:
desc = "Wheel-Down";
break;
-
default:
- goto DEFAULT;
+ sprintf(bp, "#%u", key);
+ break;
}
- strcpy(bp, desc);
+ if (desc) strcpy(bp, desc);
}
break;
- case RANGE_ASCII: {
- const char *desc = NULL,
- key8 = (char) (key & KEY_MASK);
+ case RANGE_CHARACTER: {
+ if ((key & KEY_MASK) > 0xff) {
+ sprintf(bp, "#%u", key);
+ } else {
+ const char *desc = NULL,
+ key8 = (char) (key & KEY_MASK);
- switch (key8) {
- case KEY_ENTER:
- desc = "Enter";
- break;
- case KEY_ESC:
- desc = "Esc";
- break;
- case KEY_BACKSPACE:
- desc = "Backspace";
- break;
- case KEY_TAB:
- desc = "Tab";
- break;
- case ' ':
- if (key & (MOD_META|MOD_CTRL|MOD_SHIFT)) {
- desc = "Space";
+ switch (key8) {
+ case KEY_ENTER:
+ desc = "Enter";
+ break;
+ case KEY_ESC:
+ desc = "Esc";
+ break;
+ case KEY_BACKSPACE:
+ desc = "Backspace";
+ break;
+ case KEY_TAB:
+ desc = "Tab";
+ break;
+ case ' ':
+ if (key & (MOD_META|MOD_CTRL|MOD_SHIFT)) {
+ desc = "Space";
+ }
+ break;
+ default:
+ break;
}
- break;
- default:
- break;
- }
- if (desc) {
- strcpy(bp, desc);
- bp += strlen(desc);
- } else {
- *bp++ = key8;
- *bp = '\0';
+ if (desc) {
+ strcpy(bp, desc);
+ bp += strlen(desc);
+ } else {
+ *bp++ = key8;
+ *bp = '\0';
+ }
}
}
break;
@@ -1978,7 +2032,7 @@ key_code2name(int key)
sprintf(bp, "Private-%d", key & KEY_MASK);
break;
- case RANGE_FN:
+ case RANGE_FUNCTION:
sprintf(bp, "F%d", (key & KEY_MASK) + 1);
break;
@@ -1999,9 +2053,6 @@ key_code2name(int key)
break;
case RANGE_MULTIKEY:
- case RANGE_MULTIKEY + 0x100:
- case RANGE_MULTIKEY + 0x200:
- case RANGE_MULTIKEY + 0x300:
if (NULL == x_multitbl || (key >= RANGE_MULTIKEY + x_multiseq)) {
strcpy(bp, "undefined"); /* out side range */
@@ -2038,8 +2089,7 @@ key_code2name(int key)
/*FALLTHRU*/
default:
-DEFAULT:
- sprintf(bp, "#%d", key);
+ sprintf(bp, "#%u", key);
break;
}
strcat(buf, ">");
@@ -2049,9 +2099,7 @@ key_code2name(int key)
/* Function: key_to_char
- * Function to convert a single 8-bit character into the
- * canonic notation.
- *
+ * Convert a single 8-bit character into the canonic notation.
*/
static char *
key_to_char(char *buf, int key)
@@ -2109,31 +2157,36 @@ key_to_char(char *buf, int key)
/* Function: key_execute
- * Function called to execute the macro associated
- * with an internal key code.
+ * Execute the macro associated with an internal key code.
*/
void
-key_execute(int c)
+key_execute(int key)
{
sentry_t *sep = NULL;
const char *cp;
- if (KEY_WINCH == c) {
+ assert(key >= 0);
+ if (KEY_WINCH == key) {
trace_log("\nKEY_EXEC(WINCH) 0x%x\n", KEY_WINCH);
return; /* WINCH event; ignore */
}
if (curbp && curbp->b_keyboard) { /* buffer specific */
- sep = stype_lookup(curbp->b_keyboard->kt_macros, c);
+ sep = stype_lookup(curbp->b_keyboard->kt_macros, key);
+ if (NULL == sep && IS_UNICODE(key)) {
+ sep = stype_lookup(curbp->b_keyboard->kt_macros, (stypekey_t) KEY_UNICODE);
+ }
}
if (NULL == sep) { /* current keyboard */
- sep = stype_lookup(x_kbdcur->kt_macros, c);
+ sep = stype_lookup(x_kbdcur->kt_macros, key);
+ if (NULL == sep && IS_UNICODE(key)) {
+ sep = stype_lookup(x_kbdcur->kt_macros, (stypekey_t) KEY_UNICODE);
+ }
}
if (NULL == sep) {
cp = "";
-
} else {
cp = key_macro_value((const object_t *)sep->se_ptr);
}
@@ -2142,13 +2195,12 @@ key_execute(int c)
* execute/
*/
u_chain();
- x_character = (int32_t) c; /* save internal key-code */
+ x_character = (int32_t) key; /* save internal key-code */
playback_macro(cp); /* record key-stroke */
/*
* history/
- * Commands with names beginning with an
- * underscore (_) are ignored.
+ * Commands with names beginning with an underscore (_) are ignored.
*/
assert(x_histhead >= 0);
assert(x_histhead < HIST_DEPTH);
@@ -2176,7 +2228,7 @@ key_execute(int c)
}
trace_log("\nKEY_EXEC(%s) 0x%x/%d (%02d) => %s\n",
- key_code2name(c), (unsigned)c, (int)x_character, x_histhead, cp);
+ key_code2name(key), (unsigned)key, (int)x_character, x_histhead, cp);
if (0 == *cp) {
trigger(REG_UNASSIGNED /*REG_INVALID*/);
@@ -2567,15 +2619,15 @@ cygwin_to_int(const char *buf)
* Parameters:
* dwCtrlKeyState - Control key status.
* wVirtKeyCode - Virtual key code.
- * AsciiChar - Ascii character code, if any.
+ * CharCode - Character code, if any.
*
* Results:
* nothing
*/
int
-key_mapwin32(unsigned dwCtrlKeyState, unsigned wVirtKeyCode, unsigned AsciiChar)
+key_mapwin32(unsigned dwCtrlKeyState, unsigned wVirtKeyCode, unsigned CharCode)
{
- const struct w32key *key = w32Keys + VSIZEOF(w32Keys);
+ const struct w32key *key = w32Keys + _countof(w32Keys);
int mod = 0, ch = -1;
/* modifiers */
@@ -2594,27 +2646,31 @@ key_mapwin32(unsigned dwCtrlKeyState, unsigned wVirtKeyCode, unsigned AsciiChar)
}
/* virtual keys */
- while (--key >= w32Keys)
+ while (--key >= w32Keys) {
if (key->vk == wVirtKeyCode &&
- ((key->mods == MOD_ALL) ||
- (key->mods == MOD_ENHANCED && (dwCtrlKeyState & (ENHANCED_KEY))) ||
+ ((key->mods == VKMOD_ANY) ||
+ (key->mods == VKMOD_ENHANCED && 0 != (dwCtrlKeyState & (ENHANCED_KEY))) ||
+ (key->mods == VKMOD_NONENHANCED && 0 == (dwCtrlKeyState & (ENHANCED_KEY))) ||
+ (key->mods == VKMOD_NONSHIFT && 0 == (dwCtrlKeyState & (SHIFT_PRESSED))) ||
(key->mods >= 0 && key->mods == mod) )) {
if ((ch = key->code) >= 0) {
- if (key->mods == MOD_ALL) {
+ if (key->mods == VKMOD_ANY) {
ch |= mod; /* apply modifiers */
}
}
break;
}
+ }
/* ascii */
- if (-1 == ch && (AsciiChar & 0xff)) {
- ch = (AsciiChar & 0xff); /* ASCII value */
+ assert((CharCode & ~KEY_MASK) == 0);
+ if (-1 == ch && (CharCode & KEY_MASK)) {
+ ch = (CharCode & KEY_MASK); /* UNICODE value */
if (MOD_META == mod || (MOD_META|MOD_SHIFT) == mod) {
/*
- * Special handling for ALT-ASCII .. other modifiers SHIFT and CONTROL
- * are already applied to the ASCII value.
+ * Special handling for ALT-ASCII ..
+ * other modifiers SHIFT and CONTROL are already applied to the ASCII value.
*/
if (ch >= 'a' && ch <= 'z') {
ch = toupper(ch);
@@ -2623,9 +2679,9 @@ key_mapwin32(unsigned dwCtrlKeyState, unsigned wVirtKeyCode, unsigned AsciiChar)
}
}
- trace_log("W32KEY %c%c%c = %d (%s=%s)\n",
+ trace_log("W32KEY %c%c%c = %d/0x%x (%s=%s)\n",
(mod & MOD_META ? 'M' : '.'), (mod & MOD_CTRL ? 'C' : '.'), (mod & MOD_SHIFT ? 'S' : '.'),
- ch, (ch == -1 ? "n/a" : (key >= w32Keys ? key->desc : "ASCII")), key_code2name(ch));
+ ch, ch, (ch == -1 ? "n/a" : (key >= w32Keys ? key->desc : "ASCII")), key_code2name(ch));
return (ch);
}
#endif /*WIN32 || __CYGWIN__*/
diff --git a/gr/keywd.c b/gr/keywd.c
index 92252e34..3d229f9c 100644
--- a/gr/keywd.c
+++ b/gr/keywd.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_keywd_c,"$Id: keywd.c,v 1.94 2020/06/18 14:40:37 cvsuser Exp $")
+__CIDENT_RCSID(gr_keywd_c,"$Id: keywd.c,v 1.100 2021/07/03 10:44:33 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: keywd.c,v 1.94 2020/06/18 14:40:37 cvsuser Exp $
+/* $Id: keywd.c,v 1.100 2021/07/03 10:44:33 cvsuser Exp $
* Keyword table.
*
*
@@ -119,9 +119,10 @@ const int cm_version = CM_VERSION;
#define VERSION_203
#define VERSION_204
#define VERSION_205 /* 01/04/2020, register(), __lexicalblock(), isclose() and cast_xxx() */
+#define VERSION_206 /* 06/21, UTF8 */
-// #define VERSION_206 /* array's, staged/experimental */
-// #define VERSION_207 /* not implemented/alpha */
+// #define VERSION_207 /* array's, staged/experimental */
+// #define VERSION_208 /* not implemented/alpha */
/*
* Keyword table, assumed to be in alphabetic order.
@@ -332,7 +333,7 @@ BUILTIN builtin[] = {
{"below_eq", MACRO(do_com_op), ARG_INT, 0, MOP_BELOW_EQ, /* arith */
2, {ARG_NUM | ARG_STRING, ARG_NUM | ARG_STRING}},
-#if defined(VERSION_207)
+#if defined(VERSION_208)
{"bless", MACRO(do_bless), ARG_INT, 0, 0, /* macro */
2, {ARG_INT, ARG_OPT | ARG_STRING}},
#endif
@@ -461,10 +462,7 @@ BUILTIN builtin[] = {
1, {ARG_OPT | ARG_INT}},
{"create_nested_buffer", MACRO(do_create_buffer), ARG_INT, 0, TRUE, /* buffer */
- 4, {ARG_STRING,
- ARG_OPT | ARG_STRING,
- ARG_OPT | ARG_INT,
- ARG_OPT | ARG_INT}},
+ 4, {ARG_STRING, ARG_OPT | ARG_STRING, ARG_OPT | ARG_INT, ARG_OPT | ARG_INT}},
{"create_syntax", MACRO(do_create_syntax), ARG_INT, 0, 0, /* syntax */
1, {ARG_STRING}},
@@ -926,7 +924,7 @@ BUILTIN builtin[] = {
{"get_region", MACRO(do_get_region), ARG_STRING, 0, 0, /* scrap */
1, {ARG_OPT | ARG_INT}},
-#if defined(VERSION_206)
+#if defined(VERSION_207)
{"get_system_resources", MACRO(do_get_system_resources), ARG_STRING, 0, 0, /* env */
1, {ARG_OPT | ARG_INT}},
#endif
@@ -1297,7 +1295,7 @@ BUILTIN builtin[] = {
{"inq_prompt", MACRO(inq_prompt), ARG_INT, 0, 0, /* screen */
0, {0}},
-#if defined(VERSION_206)
+#if defined(VERSION_207)
{"inq_remember_buffer", MACRO(inq_remember_buffer), ARG_STRING, 0, 0, /* kbd */
1, {ARG_OPT | ARG_INT}},
#endif
@@ -1343,9 +1341,14 @@ BUILTIN builtin[] = {
ARG_OPT | ARG_LVAL | ARG_INT,
ARG_OPT | ARG_LVAL | ARG_INT}},
- {"inq_username", MACRO(inq_username), ARG_STRING, 0, 0, /* env */
+#if defined(VERSION_206)
+ {"inq_unicode_version", MACRO(inq_unicode_version), ARG_STRING, 0, 0, /* display */
0, {0}},
+#endif
+ {"inq_username", MACRO(inq_username), ARG_STRING, 0, 0, /* env */
+ 0, {0}},
+
{"inq_vfs_mounts", MACRO(inq_vfs_mounts), ARG_LIST, 0, 0, /* file */
0, {0}},
@@ -1422,7 +1425,7 @@ BUILTIN builtin[] = {
{"int_to_key", MACRO(do_int_to_key), ARG_STRING, 0, 0, /* kbd */
1, {ARG_INT}},
-#if defined(VERSION_206)
+#if defined(VERSION_207)
#if defined(DO_ARRAY)
{"is_array", MACRO(do_is_type), ARG_INT, 0, F_ARRAY, /* var */
1, {ARG_LVAL | ARG_ANY}},
@@ -1476,7 +1479,7 @@ BUILTIN builtin[] = {
{"isfinite", MACRO(do_isfinite), ARG_INT, 0, 0, /* float, arith */
1, {ARG_FLOAT}},
-#if defined(VERSION_206)
+#if defined(VERSION_207)
{"isgold", MACRO(do_isgold), ARG_INT, 0, 0, /* string */
2, {ARG_INT | ARG_STRING, ARG_OPT | ARG_INT}},
#endif
@@ -1548,7 +1551,7 @@ BUILTIN builtin[] = {
{"length_of_list", MACRO(do_length_of_list), ARG_INT, 0, 0, /* list */
1, {ARG_LIST}},
-#if defined(VERSION_206)
+#if defined(VERSION_207)
{"link", MACRO(do_link), ARG_INT, 0, 0, /* file */
3, {ARG_STR, ARG_STR, ARG_OPT | ARG_INT}},
#endif
@@ -2061,6 +2064,11 @@ BUILTIN builtin[] = {
ARG_OPT | ARG_INT,
ARG_OPT | ARG_INT}},
+#if defined(VERSION_206)
+ {"set_unicode_version", MACRO(do_set_unicode_version), ARG_INT, 0, 0, /* display */
+ 1, {ARG_STRING}},
+#endif
+
{"set_window", MACRO(do_set_window), ARG_INT, 0, 0, /* window */
1, {ARG_INT}},
@@ -2117,7 +2125,7 @@ BUILTIN builtin[] = {
{"spell_distance", MACRO(do_spell_distance), ARG_UNDEF, 0, 0, /* spell */
2, {ARG_STRING, ARG_STRING}},
-#if defined(VERSION_206)
+#if defined(VERSION_207)
{"spell_dictionary", MACRO(do_spell_dictionary), ARG_UNDEF, 0, 0, /* spell */
-3, {ARG_INT, ARG_OPT|ARG_INT, ARG_STRING|ARG_LIST}},
#endif
@@ -2334,7 +2342,7 @@ BUILTIN builtin[] = {
{"undo", MACRO(do_undo), ARG_INT, 0, -1, /* buffer, kbd */
3, {ARG_OPT | ARG_INT, ARG_OPT | ARG_INT, ARG_OPT | ARG_INT}},
-#if defined(VERSION_206)
+#if defined(VERSION_207)
{"unlink", MACRO(do_unlink), ARG_INT, 0, 0, /* file */
2, {ARG_STR, ARG_OPT | ARG_INT}},
#endif
@@ -2388,6 +2396,17 @@ BUILTIN builtin[] = {
{"watch", MACRO(do_unimp), ARG_VOID, 0, 0, /* debug */
0, {0}},
+#if defined(VERSION_206)
+ {"wcharacterat", MACRO(do_wcharacterat), ARG_INT, 0, 0, /* string */
+ 2, {ARG_STRING, ARG_INT}},
+
+ {"wcwidth", MACRO(do_wcwidth), ARG_INT, 0, 0, /* string */
+ 2, {ARG_INT | ARG_STRING, ARG_OPT | ARG_INT}},
+
+ {"wfirstof", MACRO(do_wfirstof), ARG_INT, 0, 0, /* string */
+ 3, {ARG_STRING, ARG_STRING, ARG_OPT | ARG_LVAL | ARG_INT}},
+#endif
+
{"while", MACRO(do_while), ARG_VOID, 0, 0, /* macro */
2, {ARG_COND, ARG_OPT | ARG_REST}},
@@ -2401,15 +2420,63 @@ BUILTIN builtin[] = {
ARG_OPT | ARG_INT,
ARG_OPT | ARG_INT}},
+#if defined(VERSION_206)
+ {"windex", MACRO(do_windex), ARG_INT, 0, 0, /* string */
+ 2, {ARG_STRING, ARG_INT | ARG_STRING}},
+#endif
+
{"window_color", MACRO(do_window_color), ARG_INT, 0, 0, /* window, screen */
2, {ARG_OPT | ARG_INT, ARG_OPT | ARG_INT}},
+#if defined(VERSION_206)
+ {"wlastof", MACRO(do_wlastof), ARG_INT, 0, 0, /* string */
+ 3, {ARG_STRING, ARG_STRING, ARG_OPT | ARG_LVAL | ARG_INT }},
+
+ {"wlower", MACRO(do_wlower), ARG_STRING, 0, 0, /* string */
+ 1, {ARG_INT | ARG_STRING}},
+
+ {"wrindex", MACRO(do_wrindex), ARG_INT, 0, 0, /* string */
+ 2, {ARG_STRING, ARG_INT | ARG_STRING}},
+#endif
+
{"write_block", MACRO(do_write_block), ARG_INT, 0, 0, /* file, scrap */
4, {ARG_OPT | ARG_STRING, ARG_OPT | ARG_INT, ARG_OPT | ARG_INT, ARG_OPT | ARG_INT}},
{"write_buffer", MACRO(do_write_buffer), ARG_INT, 0, 0, /* file, buffer */
2, {ARG_OPT | ARG_STRING, ARG_OPT | ARG_INT}},
+ {"write_buffer", MACRO(do_write_buffer), ARG_INT, 0, 0, /* file, buffer */
+ 2, {ARG_OPT | ARG_STRING, ARG_OPT | ARG_INT}},
+
+#if defined(VERSION_206)
+ {"wstrcasecmp", MACRO(do_wstrcasecmp), ARG_INT, 0, 0, /* string */
+ 3, {ARG_STRING, ARG_STRING, ARG_OPT | ARG_INT}},
+
+ {"wstrcmp", MACRO(do_wstrcmp), ARG_INT, 0, 0, /* string */
+ 3, {ARG_STRING, ARG_STRING, ARG_OPT | ARG_INT}},
+
+ {"wstrlen", MACRO(do_wstrlen), ARG_INT, 0, 0, /* string */
+ 2, {ARG_STRING | ARG_LIST, ARG_OPT | ARG_INT}},
+
+ {"wstrnlen", MACRO(do_wstrnlen), ARG_INT, 0, 0, /* string */
+ 3, {ARG_STRING | ARG_LIST, ARG_INT, ARG_OPT | ARG_INT}},
+
+ {"wstrpbrk", MACRO(do_wstrpbrk), ARG_INT, 0, 0, /* string */
+ 2, {ARG_STRING, ARG_STRING}},
+
+ {"wstrrstr", MACRO(do_wstrrstr), ARG_INT, 0, 0, /* string */
+ 2, {ARG_STRING, ARG_STRING}},
+
+ {"wstrstr", MACRO(do_wstrstr), ARG_INT, 0, 0, /* string */
+ 2, {ARG_STRING, ARG_STRING}},
+
+ {"wsubstr", MACRO(do_wsubstr), ARG_STRING, 0, 0, /* string */
+ 3, {ARG_STRING, ARG_INT, ARG_OPT | ARG_INT}},
+
+ {"wupper", MACRO(do_wupper), ARG_STRING, 0, 0, /* string */
+ 1, {ARG_INT | ARG_STRING}},
+#endif
+
{"|", MACRO(do_com_op), ARG_UNDEF, 0, MOP_BOR, /* arith */
2, {ARG_INT, ARG_INT}},
@@ -2480,7 +2547,7 @@ builtin_init(void)
#if !defined(__NOFUNCTIONS__)
if (i && b_sort(bp - 1, bp) > 0) {
- trace_log("\t'%s' and '%s' are not ordered\n", bp[-1].b_name, bp->b_name);
+ trace_log("\t'%s' and '%s' are not ordered\n", bp[-1].b_name, c_string(bp->b_name));
}
#endif
}
diff --git a/gr/kill.c b/gr/kill.c
index 6528583d..bc614d8b 100644
--- a/gr/kill.c
+++ b/gr/kill.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_kill_c,"$Id: kill.c,v 1.22 2020/04/21 00:01:55 cvsuser Exp $")
+__CIDENT_RCSID(gr_kill_c,"$Id: kill.c,v 1.23 2021/10/18 13:17:45 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: kill.c,v 1.22 2020/04/21 00:01:55 cvsuser Exp $
+/* $Id: kill.c,v 1.23 2021/10/18 13:17:45 cvsuser Exp $
* Scrap buffer.
*
*
@@ -34,8 +34,8 @@ __CIDENT_RCSID(gr_kill_c,"$Id: kill.c,v 1.22 2020/04/21 00:01:55 cvsuser Exp $")
#include "undo.h"
-#define K_START BUFFER_t *savedbp = curbp; curbp = scrbp; set_hooked()
-#define K_END curbp = savedbp; set_hooked()
+#define K_START BUFFER_t *savedbp = curbp; set_curbp(scrbp)
+#define K_END set_curbp(savedbp)
static BUFFER_t * scrap_bp = NULL; /* system scrap buffer */
diff --git a/gr/line.c b/gr/line.c
index 2bd9003e..8238f190 100644
--- a/gr/line.c
+++ b/gr/line.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_line_c,"$Id: line.c,v 1.44 2020/06/05 15:40:35 cvsuser Exp $")
+__CIDENT_RCSID(gr_line_c,"$Id: line.c,v 1.46 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: line.c,v 1.44 2020/06/05 15:40:35 cvsuser Exp $
+/* $Id: line.c,v 1.46 2021/07/05 15:01:27 cvsuser Exp $
* Line management.
*
*
@@ -24,7 +24,6 @@ __CIDENT_RCSID(gr_line_c,"$Id: line.c,v 1.44 2020/06/05 15:40:35 cvsuser Exp $")
#include
#include "../libvfs/vfs.h"
-#include "../libchartable/libchartable.h"
#include "accum.h" /* acc_...() */
#include "anchor.h" /* anchor_...() */
@@ -416,7 +415,7 @@ lchange(int flag, LINENO count)
if (count < 1) count = 1;
for (cline = line, eline = line + count; cline < eline; ++cline) {
- if (NULL != (lp = linep(cline))) {
+ if (NULL != (lp = vm_lock_line(cline))) {
const LINENO length = llength(lp);
if (bp->b_maxlinep == lp) { /* length change? */
@@ -432,6 +431,8 @@ lchange(int flag, LINENO count)
bp->b_maxlinep = (LINE_t *)lp;
}
}
+
+ vm_unlock(cline);
}
}
}
@@ -627,7 +628,7 @@ linsertc(int ch)
const int isutf8 = buf_isutf8(bp); /* legacy/dialog buffer encoding */
if (isutf8 && MCHAR_ISUTF8(ch)) {
- linsert((const char *)buffer, mchar_ucs_encode(ch, buffer), FALSE);
+ linsert((const char *)buffer, Wctoutf8(ch, buffer, sizeof(buffer)), FALSE);
} else { /* NORMAL */
*((unsigned char *)buffer) = (unsigned char) ch;
@@ -708,10 +709,10 @@ lnewline(void)
return;
}
llinepad();
- if (NULL != (lp = vm_lock_line(cline))) {
+ if (NULL != (lp = vm_lock_line2(cline))) {
assert(cline == *cur_line);
assert(ccol == *cur_col);
- newlinedot(lp, line_offset2(lp, cline, ccol, LOFFSET_NORMAL_MATCH));
+ newlinedot(lp, line_offset_const(lp, cline, ccol, LOFFSET_NORMAL_MATCH));
vm_unlock(cline);
}
}
@@ -798,10 +799,12 @@ linsert(const char *buffer, LINENO length, int nl)
assert(nl || length > 0);
llinepad();
- lp = vm_lock_line(cline);
- assert(lp != x_static_line);
+ lp = vm_lock_line2(cline);
+ assert(lp);
+ if (NULL == lp)
+ goto false_exit;
- dot = line_offset2(lp, cline, ccol, LOFFSET_FILL_VSPACE);
+ dot = line_offset_fill(lp, cline, ccol, LOFFSET_FILL_VSPACE);
if (length) {
if (FALSE == lexpand(lp, dot, length)) {
goto false_exit;
@@ -860,8 +863,8 @@ lwrite(const char *buffer, LINENO length, int characters)
int replace = FALSE;
LINE_t *lp;
- lp = vm_lock_line(cline);
- dot = line_offset2(lp, cline, ccol, LOFFSET_FILL_SPACE);
+ lp = vm_lock_line2(cline);
+ dot = line_offset_fill(lp, cline, ccol, LOFFSET_FILL_SPACE);
count = line_sizeregion(lp, ccol, dot, characters, &olength, NULL);
if (olength < length) {
if ((dot + length) <= (LINENO)llength(lp)) {
@@ -891,6 +894,7 @@ lwrite(const char *buffer, LINENO length, int characters)
}
}
}
+
*cur_col += characters; /* XXX - issues when line is filled */
vm_unlock(cline);
}
@@ -910,7 +914,7 @@ ldeletec(int cnt)
while (cnt > 0) {
const LINENO cline = *cur_line, ccol = *cur_col;
const LINENO numlines = curbp->b_numlines;
- LINENO count, length, dot;
+ LINENO count = 1, length, dot;
LINE_t *lp;
ED_TRACE(("\tline:%d,col:%d,numlines:%d,cnt:%d\n", cline, ccol, numlines, cnt))
@@ -920,14 +924,15 @@ ldeletec(int cnt)
break;
}
- lp = vm_lock_line(cline);
- dot = line_offset2(lp, cline, ccol, LOFFSET_NORMAL_MATCH);
- if (0 == (count = line_sizeregion(lp, ccol, dot, cnt, &length, NULL))) {
- count = length = 1; /* */
+ if (NULL != (lp = vm_lock_line2(cline))) {
+ dot = line_offset_const(lp, cline, ccol, LOFFSET_NORMAL_MATCH);
+ if (0 == (count = line_sizeregion(lp, ccol, dot, cnt, &length, NULL))) {
+ count = length = 1; /* */
+ }
+ ldeletedot(length, dot);
+ vm_unlock(cline);
}
- ldeletedot(length, dot);
- vm_unlock(cline);
- cnt -= count;
+ cnt -= count; /* MCHAR/characters */
}
ED_TRACE(("==> cnt:%d\n", cnt))
}
@@ -1029,19 +1034,20 @@ lreplacedot(const char *buffer, int ins, int del, int dot, int *edot)
/*
* simple case/
- * insert-size < delete-size and no new-lines
+ * insert-size < delete-size and no new-lines.
*/
- lp = vm_lock_line(cline);
- if (ledit(lp, 0)) {
- lchange(WFEDIT, 0);
- u_replace((const char *)(ltext(lp) + dot), del, ins);
- if (diff) {
- line_move(lp, dot + ins, dot + del, llength(lp) - dot - del);
- lp->l_used -= diff;
+ if (NULL != (lp = vm_lock_line2(cline))) {
+ if (ledit(lp, 0)) {
+ lchange(WFEDIT, 0);
+ u_replace((const char *)(ltext(lp) + dot), del, ins);
+ if (diff) {
+ line_move(lp, dot + ins, dot + del, llength(lp) - dot - del);
+ lp->l_used -= diff;
+ }
+ line_set(lp, dot, buffer, ins, *cur_attr, 1);
}
- line_set(lp, dot, buffer, ins, *cur_attr, 1);
+ vm_unlock(cline);
}
- vm_unlock(cline);
if (edot) {
*edot = dot + ins;
}
@@ -1072,8 +1078,7 @@ ldeletedot(LINENO cnt, int dot)
ED_TRACE(("ldeletedot(line:%d, col:%d, dot:%d, cnt:%d)\n", *cur_line, *cur_col, dot, cnt))
assert(cnt > 0);
- if (NULL == (lp = vm_lock_line(cline))) {
- vm_unlock(cline);
+ if (NULL == (lp = vm_lock_line2(cline))) {
return;
}
@@ -1505,4 +1510,5 @@ line_set(LINE_t *lp, LINENO dst, const char *src, LINENO len, LINEATTR attr, LIN
}
}
}
+
/*end*/
diff --git a/gr/lisp.c b/gr/lisp.c
index 2f237a8b..a6787190 100644
--- a/gr/lisp.c
+++ b/gr/lisp.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_lisp_c,"$Id: lisp.c,v 1.44 2020/06/18 14:40:37 cvsuser Exp $")
+__CIDENT_RCSID(gr_lisp_c,"$Id: lisp.c,v 1.45 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: lisp.c,v 1.44 2020/06/18 14:40:37 cvsuser Exp $
+/* $Id: lisp.c,v 1.45 2021/07/05 15:01:27 cvsuser Exp $
* List primitives.
*
*
@@ -652,7 +652,7 @@ atom_assign_sym(const LIST *lp, SYMBOL *sp)
case F_NULL:
return 1;
-// case F_STR:
+// case F_STR:
// case F_ID:
// case F_SYM:
// case F_REG:
diff --git a/gr/lock.c b/gr/lock.c
index 19dc609a..048bfc6e 100644
--- a/gr/lock.c
+++ b/gr/lock.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_lock_c,"$Id: lock.c,v 1.30 2020/06/03 16:22:15 cvsuser Exp $")
+__CIDENT_RCSID(gr_lock_c,"$Id: lock.c,v 1.31 2021/06/02 13:25:28 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: lock.c,v 1.30 2020/06/03 16:22:15 cvsuser Exp $
+/* $Id: lock.c,v 1.31 2021/06/02 13:25:28 cvsuser Exp $
* File locking support.
When two users edit the same file at the same time, they are likely
@@ -263,11 +263,7 @@ info_get(const char *lfile, Info_t *i)
memset((char *)i, 0, sizeof (*i)); /* zap */
/* is symbolic link? */
-#if defined(unix) || defined(__APPLE__)
- if (lstat(lfile, &st) == -1)
-#else
if (sys_lstat(lfile, &st) == -1)
-#endif
{
if (errno == ENOENT) {
return 1; /* doesnt exist */
@@ -285,17 +281,10 @@ info_get(const char *lfile, Info_t *i)
// n >= (int)sizeof(buf)-1) {
// return -1;
// }
-#if defined(unix) || defined(__APPLE__)
- if ((n = readlink(lfile, buf, sizeof (buf)-1)) == -1 ||
- n >= (int)sizeof(buf)-1) {
- return -1;
- }
-#else
if ((n = sys_readlink(lfile, buf, sizeof (buf)-1)) == -1 ||
n >= (int)sizeof(buf)-1) {
return -1;
}
-#endif
buf[n] = '\0';
/* user */
@@ -366,11 +355,7 @@ info_get(const char *lfile, Info_t *i)
static int
lck_create(const Info_t *i, const char *buf)
{
-#if defined(unix) || defined(__APPLE__)
- return symlink(buf, i->i_file);
-#else
return sys_symlink(buf, i->i_file);
-#endif
}
@@ -387,11 +372,7 @@ static int
lck_remove(const Info_t *i)
{
if (i->i_file) {
-#if defined(unix) || defined(__APPLE__)
- return unlink(i->i_file);
-#else
return sys_unlink(i->i_file);
-#endif
}
return -1;
}
diff --git a/gr/m_backup.c b/gr/m_backup.c
index 1d16cec0..89bb145f 100644
--- a/gr/m_backup.c
+++ b/gr/m_backup.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_backup_c,"$Id: m_backup.c,v 1.18 2014/10/22 02:33:00 ayoung Exp $")
+__CIDENT_RCSID(gr_m_backup_c,"$Id: m_backup.c,v 1.19 2021/06/02 13:40:03 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_backup.c,v 1.18 2014/10/22 02:33:00 ayoung Exp $
+/* $Id: m_backup.c,v 1.19 2021/06/02 13:40:03 cvsuser Exp $
* File backup option/configuration primitives.
*
*
@@ -25,6 +25,7 @@ __CIDENT_RCSID(gr_m_backup_c,"$Id: m_backup.c,v 1.18 2014/10/22 02:33:00 ayoung
#include "m_backup.h" /* public interface */
+#include "system.h"
#include "accum.h" /* acc_...() */
#include "buffer.h" /* buf_...() */
#include "debug.h" /* trace_...() */
@@ -202,7 +203,7 @@ bkcfg_ask(const char *fname)
if (! xf_backups) {
ret = FALSE;
} else {
- if (stat(fname, &sb) >= 0) {
+ if (sys_stat(fname, &sb) >= 0) {
if (x_backup_dont && sb.st_size >= x_backup_dont) {
ret = FALSE;
} else if (x_backup_ask && sb.st_size >= x_backup_ask) {
diff --git a/gr/m_buf.c b/gr/m_buf.c
index 842dad0d..1f67d435 100644
--- a/gr/m_buf.c
+++ b/gr/m_buf.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_buf_c,"$Id: m_buf.c,v 1.55 2020/06/03 16:18:30 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_buf_c,"$Id: m_buf.c,v 1.56 2021/10/18 13:12:49 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_buf.c,v 1.55 2020/06/03 16:18:30 cvsuser Exp $
+/* $Id: m_buf.c,v 1.56 2021/10/18 13:12:49 cvsuser Exp $
* Buffer primitives.
*
*
@@ -1994,8 +1994,7 @@ do_set_buffer(void) /* int (int bufnum) */
curbp->b_col = curwp->w_col;
curbp->b_top = curwp->w_top_line;
}
- curbp = bp;
- set_hooked();
+ set_curbp(bp);
}
@@ -2124,8 +2123,7 @@ do_create_edge(void) /* int ([int direction]) */
if (wp) {
if (WD_RIGHT == i || WD_DOWN == i) {
- curwp = wp;
- set_hooked();
+ set_curwp(wp);
}
ret = 1;
} else {
diff --git a/gr/m_display.c b/gr/m_display.c
index 4f03cde7..f29b1708 100644
--- a/gr/m_display.c
+++ b/gr/m_display.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_display_c,"$Id: m_display.c,v 1.27 2020/06/05 15:51:34 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_display_c,"$Id: m_display.c,v 1.29 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_display.c,v 1.27 2020/06/05 15:51:34 cvsuser Exp $
+/* $Id: m_display.c,v 1.29 2021/07/05 15:01:27 cvsuser Exp $
* Display primitives.
*
*
@@ -503,7 +503,7 @@ flag_override(const char *name, int length, int *value)
trace_ilog(value ? "\t %*s=%d\n" : "\t %*s\n", namelength, name, (value ? *value : -1));
for (i = 0; i < (unsigned)(sizeof(doflagnames)/sizeof(doflagnames[0])); ++i)
- if (namelength == (size_t)doflagnames[i].f_length &&
+ if (namelength == doflagnames[i].f_length &&
0 == str_nicmp(doflagnames[i].f_name, name, namelength)) {
return doflagnames[i].f_value;
}
@@ -864,4 +864,5 @@ do_view_screen(void) /* int () */
}
acc_assign_int(ret);
}
+
/*end*/
diff --git a/gr/m_errno.c b/gr/m_errno.c
index 8439d62e..c02da1b4 100644
--- a/gr/m_errno.c
+++ b/gr/m_errno.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_errno_c,"$Id: m_errno.c,v 1.26 2014/10/22 02:33:02 ayoung Exp $")
+__CIDENT_RCSID(gr_m_errno_c,"$Id: m_errno.c,v 1.27 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_errno.c,v 1.26 2014/10/22 02:33:02 ayoung Exp $
+/* $Id: m_errno.c,v 1.27 2021/07/05 15:01:27 cvsuser Exp $
* errno symbol primitives.
*
*
@@ -845,7 +845,7 @@ do_perror(void) /* ([int errno], string format, ...) */
{
int msglen = -1, errlen;
const int xerrno = get_xinteger(1, (int) *x_errno_ptr);
- const char *msg = print_formatted(2, &msglen);
+ const char *msg = print_formatted(2, &msglen, NULL);
char err[80];
errlen = sxprintf(err, sizeof(err), ": %s (%d)", str_error(xerrno), xerrno);
diff --git a/gr/m_file.c b/gr/m_file.c
index cf9fdab3..b8d839b6 100644
--- a/gr/m_file.c
+++ b/gr/m_file.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_file_c,"$Id: m_file.c,v 1.41 2021/04/16 11:45:43 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_file_c,"$Id: m_file.c,v 1.43 2021/06/19 09:42:03 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_file.c,v 1.41 2021/04/16 11:45:43 cvsuser Exp $
+/* $Id: m_file.c,v 1.43 2021/06/19 09:42:03 cvsuser Exp $
* File primitives.
*
*
@@ -326,7 +326,7 @@ do_searchpath(void) /* int (string searchpath, string file, [string
strxcat(path, extension, sizeof(path));
}
- if (0 == stat(path, &sb)) {
+ if (0 == sys_stat(path, &sb)) {
const char *result = path;
if (expand) {
@@ -1468,7 +1468,7 @@ do_mkdir(void) /* (string pathname, int mode = 0755) */
if (ret && EEXIST != ret) {
struct stat sb;
- if (0 == stat(pathname, &sb) && S_ISDIR(sb.st_mode)) {
+ if (0 == sys_stat(pathname, &sb) && S_ISDIR(sb.st_mode)) {
ret = 0; /* ignore, false error */
}
}
@@ -2781,11 +2781,7 @@ do_readlink(void) /* string (string path, [string &link]) */
//TODO
// path = file_tilder(path, t_path, sizeof(t_path));
// if (vfs_readlink(name, link, sizeof(link)-1) == -1)
-#if defined(unix) || defined(__APPLE__)
- if ((ret = readlink(name, linkpath, sizeof(linkpath)-1)) <= -1) {
-#else
if ((ret = sys_readlink(name, linkpath, sizeof(linkpath)-1)) <= -1) {
-#endif
acc_assign_int(errno == ENOSYS ? 0 : -1);
} else {
@@ -2939,12 +2935,7 @@ do_symlink(void) /* int (string, string) */
int ret = -1;
if (path1 && path2) {
-#if defined(unix) || defined(__APPLE__)
- if ((ret = symlink(path1, path2)) <= -1)
-#else
- if ((ret = sys_symlink(path1, path2)) <= -1)
-#endif
- {
+ if ((ret = sys_symlink(path1, path2)) <= -1) {
system_call(ret);
}
} else {
@@ -3418,5 +3409,5 @@ do_mktemp(void) /* string (string path) */
acc_assign_str("", -1);
}
}
-/*end*/
+/*end*/
diff --git a/gr/m_line.c b/gr/m_line.c
index cffa6ed2..e0cbda6b 100644
--- a/gr/m_line.c
+++ b/gr/m_line.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_line_c,"$Id: m_line.c,v 1.19 2020/04/21 00:01:56 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_line_c,"$Id: m_line.c,v 1.20 2021/06/10 06:13:02 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_line.c,v 1.19 2020/04/21 00:01:56 cvsuser Exp $
+/* $Id: m_line.c,v 1.20 2021/06/10 06:13:02 cvsuser Exp $
* Line primitives.
*
*
@@ -188,6 +188,7 @@ do_find_marker(void) /* int ([int marker = L_MARKED]) */
const lineflags_t marker = get_xinteger(1, L_MARKED);
const LINENO numlines = curbp->b_numlines;
LINENO line;
+ LINE_t *lp;
int ret = 0;
if (0 == (L_USER_MASK & marker) || 1 != flagcount(marker)) {
@@ -196,16 +197,16 @@ do_find_marker(void) /* int ([int marker = L_MARKED]) */
}
for (line = *cur_line + 1; line <= numlines; ++line) { /*NEWLINE*/
- LINE_t *lp = vm_lock_line(line);
-
- if (marker & lp->l_uflags) {
- lp->l_uflags &= ~marker; /* clear */
+ if (NULL != (lp = vm_lock_line2(line))) {
+ if (marker & lp->l_uflags) {
+ lp->l_uflags &= ~marker; /* clear */
+ vm_unlock(line);
+ *cur_line = line;
+ ret = 1;
+ break;
+ }
vm_unlock(line);
- *cur_line = line;
- ret = 1;
- break;
}
- vm_unlock(line);
}
acc_assign_int(ret);
@@ -362,11 +363,12 @@ do_set_line_flags(void) /* int ([int bufnum], [int start], [int end], [i
}
for (line = start; line < end; ++line) {
- LINE_t *lp = vm_lock_line(line);
-
- lp->l_uflags &= and_mask;
- lp->l_uflags |= or_value;
- vm_unlock(line);
+ LINE_t *lp = vm_lock_line2(line);
+ if (lp) {
+ lp->l_uflags &= and_mask;
+ lp->l_uflags |= or_value;
+ vm_unlock(line);
+ }
++ret;
}
}
@@ -473,7 +475,7 @@ do_find_line_flags(void) /* int ([int bufnum], [int lineno],
LINENO line;
for (line = (uint32_t) start; line; --line) {
- LINE_t *lp = vm_lock_line(line);
+ const LINE_t *lp = vm_lock_line(line);
if (((mode & LF_MATCH_EQ) && (((lp->l_uflags & and_mask) | or_value) == value)) ||
((mode & LF_MATCH_ANY) && ((lp->l_uflags & and_mask) != 0))) {
diff --git a/gr/m_mchar.c b/gr/m_mchar.c
index b8198610..a6d4a7e2 100644
--- a/gr/m_mchar.c
+++ b/gr/m_mchar.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_mchar_c,"$Id: m_mchar.c,v 1.11 2014/10/22 02:33:05 ayoung Exp $")
+__CIDENT_RCSID(gr_m_mchar_c,"$Id: m_mchar.c,v 1.15 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_mchar.c,v 1.11 2014/10/22 02:33:05 ayoung Exp $
+/* $Id: m_mchar.c,v 1.15 2021/07/05 15:01:27 cvsuser Exp $
* Multibyte/locale primitives.
*
*
@@ -22,6 +22,8 @@ __CIDENT_RCSID(gr_m_mchar_c,"$Id: m_mchar.c,v 1.11 2014/10/22 02:33:05 ayoung Ex
#include
#include "m_mchar.h"
+#include "../libchartable/libchartable.h"
+#include "../libwidechar/widechar.h"
#include "accum.h" /* acc_...() */
#include "buffer.h" /* buf_...() */
@@ -89,12 +91,12 @@ __CIDENT_RCSID(gr_m_mchar_c,"$Id: m_mchar.c,v 1.11 2014/10/22 02:33:05 ayoung Ex
! SCSU BFTYP_SCSU
! UTF-7 BFTYP_UTF7 65002
- ! UTF-4 BFTYP_UCS4
- ! UTF-4be BFTYP_UCS4
- ! UTF-4le BFTYP_UCS4
- ! UTF-2 BFTYP_UCS2
+ ! UTF-2 BFTYP_UCS2 BFTYP_UTF16 aliases
! UTF-2be BFTYP_UCS2
! UTF-2le BFTYP_UCS2
+ ! UTF-4 BFTYP_UCS4 BFTYP_UTF32 aliases
+ ! UTF-4be BFTYP_UCS4
+ ! UTF-4le BFTYP_UCS4
! cp437 BFTYP_SBCS 437 OEM/US, ASCII
! cp737 BFTYP_SBCS 737 Greek, ISO-8859-7
@@ -301,4 +303,43 @@ inq_encodings(void) /* list ([int flags]) */
{
//TODO
}
+
+
+void
+do_wcwidth(void) /* int (string str | int character), [int default]] */
+{
+ int width = -1;
+
+ if (isa_integer(1)) {
+ if ((width = ucs_width(get_xinteger(1, 0))) < 0) {
+ width = get_xinteger(2, -1);
+ }
+
+ } else if (isa_string(1)) {
+ width = utf8_swidth(get_str(1));
+ }
+
+ acc_assign_int((accint_t) width);
+}
+
+
+void
+do_set_unicode_version(void)
+{
+ int version = -1;
+
+ if (isa_string(1)) {
+ version = ucs_width_set(get_str(1));
+ }
+
+ acc_assign_int((accint_t) version);
+}
+
+
+void
+inq_unicode_version(void)
+{
+ acc_assign_str(ucs_width_version(), -1);
+}
+
/*end*/
diff --git a/gr/m_mchar.h b/gr/m_mchar.h
index 070c11bc..5214f23f 100644
--- a/gr/m_mchar.h
+++ b/gr/m_mchar.h
@@ -1,11 +1,11 @@
#ifndef GR_M_MCHAR_H_INCLUDED
#define GR_M_MCHAR_H_INCLUDED
#include
-__CIDENT_RCSID(gr_m_mchar_h,"$Id: m_mchar.h,v 1.7 2014/10/22 02:33:05 ayoung Exp $")
+__CIDENT_RCSID(gr_m_mchar_h,"$Id: m_mchar.h,v 1.9 2021/06/13 16:01:34 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_mchar.h,v 1.7 2014/10/22 02:33:05 ayoung Exp $
+/* $Id: m_mchar.h,v 1.9 2021/06/13 16:01:34 cvsuser Exp $
* Multiple-byte/local primitives.
*
*
@@ -29,6 +29,10 @@ extern void do_set_encoding(void);
extern void inq_encoding(void);
extern void inq_encodings(void);
+extern void do_wcwidth(void);
+extern void do_set_unicode_version(void);
+extern void inq_unicode_version(void);
+
__CEND_DECLS
#endif /*GR_M_MCHAR_H_INCLUDED*/
diff --git a/gr/m_msg.c b/gr/m_msg.c
index eb660d3c..965767d8 100644
--- a/gr/m_msg.c
+++ b/gr/m_msg.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_msg_c,"$Id: m_msg.c,v 1.30 2014/10/27 23:27:55 ayoung Exp $")
+__CIDENT_RCSID(gr_m_msg_c,"$Id: m_msg.c,v 1.31 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_msg.c,v 1.30 2014/10/27 23:27:55 ayoung Exp $
+/* $Id: m_msg.c,v 1.31 2021/07/05 15:01:27 cvsuser Exp $
* Message and formatting primitives.
*
*
@@ -435,7 +435,7 @@ void
do_message(void) /* (string format, ...) */
{
int len = -1;
- const char *cp = print_formatted(0, &len);
+ const char *cp = print_formatted(0, &len, NULL);
if (cp && len) {
infos(cp);
@@ -523,7 +523,7 @@ void
do_error(void) /* int (string format, ...) */
{
int len = -1;
- const char *cp = print_formatted(0, &len);
+ const char *cp = print_formatted(0, &len, NULL);
if (cp && len) {
errorf("%s", cp);
@@ -630,7 +630,7 @@ do_print(void) /* int () */
void
do_printf(void) /* (string format, ...) */
{
- const char *cp = print_formatted(0, NULL);
+ const char *cp = print_formatted(0, NULL, NULL);
if (NULL == cp) {
acc_assign_int(-1);
@@ -714,7 +714,7 @@ do_printf(void) /* (string format, ...) */
void
do_dprintf(void) /* (string format, ...) */
{
- const char *cp = print_formatted(0, NULL);
+ const char *cp = print_formatted(0, NULL, NULL);
if (NULL == cp) {
acc_assign_int(-1);
@@ -787,13 +787,13 @@ do_sprintf(void) /* int (string buffer, string format, ...) */
{
SYMBOL *sp = get_symbol(1);
const char *cp;
- int len = 0;
+ int len = 0, width = 0;
- cp = print_formatted(1, &len);
+ cp = print_formatted(1, &len, &width);
if (cp) {
sym_assign_str(sp, cp);
}
- acc_assign_int(len);
+ acc_assign_int(width);
}
@@ -857,9 +857,10 @@ void
do_format(void) /* (string format, ...) */
{
const char *cp;
+ int len = 0;
- cp = print_formatted(0, NULL);
- acc_assign_str(cp, -1);
+ cp = print_formatted(0, &len, NULL);
+ acc_assign_str(cp, len);
}
diff --git a/gr/m_pty.c b/gr/m_pty.c
index 5a4b4ad0..698420fd 100644
--- a/gr/m_pty.c
+++ b/gr/m_pty.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_pty_c,"$Id: m_pty.c,v 1.23 2020/04/21 00:01:56 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_pty_c,"$Id: m_pty.c,v 1.25 2021/10/18 13:12:13 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_pty.c,v 1.23 2020/04/21 00:01:56 cvsuser Exp $
+/* $Id: m_pty.c,v 1.25 2021/10/18 13:12:13 cvsuser Exp $
*
*
* This file is part of the GRIEF Editor.
@@ -904,9 +904,8 @@ p_push(BUFFER_t *bp, const char *str)
DISPLAY_t *dp = bp->b_display;
const char *start = NULL;
- curbp = bp;
+ set_curbp(bp);
BFSET(curbp, BF_NO_UNDO);
- set_hooked();
if ((*cur_line = dp->d_curline) < 1) {
*cur_line = 1;
@@ -1029,11 +1028,10 @@ p_push(BUFFER_t *bp, const char *str)
if (curwp && curwp->w_bufp == curbp) {
set_buffer_parms(bp, curwp);
}
- curbp = saved_bp;
+ set_curbp(saved_bp);
if (! saved_no_undo) {
BFCLR(curbp, BF_NO_UNDO);
}
- set_hooked();
}
@@ -1379,7 +1377,7 @@ p_escape_decode(DISPLAY_t *dp)
*/
if (NULL != (lp = linepx(curbp, cline))) {
if ((length = llength(lp)) > 0) {
- dot = line_offset2(lp, cline, ccol, LOFFSET_FIRSTBYTE);
+ dot = line_offset_const(lp, cline, ccol, LOFFSET_FIRSTBYTE);
dellen = p_sgrlength(ltext(lp) + dot, ltext(lp) + length, 'm');
}
vm_unlock(cline);
@@ -1584,7 +1582,7 @@ void
pty_poll(void)
{
static int entry = 0;
- BUFFER_t *saved_curbp = curbp;
+ BUFFER_t *ocurbp = curbp;
int updated;
char buf[1024+1];
@@ -1631,8 +1629,7 @@ pty_poll(void)
* Update screen if necessary and make sure that the current buffer is restored
* so that cursor goes at right place and in case we exit this loop
*/
- curbp = saved_curbp;
- set_hooked();
+ set_curbp(ocurbp);
if (updated) {
vtupdate();
}
diff --git a/gr/m_spell.c b/gr/m_spell.c
index b872b4ae..67bd701f 100644
--- a/gr/m_spell.c
+++ b/gr/m_spell.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_spell_c,"$Id: m_spell.c,v 1.42 2020/04/21 00:01:56 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_spell_c,"$Id: m_spell.c,v 1.43 2021/06/10 06:13:02 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_spell.c,v 1.42 2020/04/21 00:01:56 cvsuser Exp $
+/* $Id: m_spell.c,v 1.43 2021/06/10 06:13:02 cvsuser Exp $
* Spell primitives.
*
* Enchant - AbiWord spell-checker generic interface
@@ -22,7 +22,6 @@ __CIDENT_RCSID(gr_m_spell_c,"$Id: m_spell.c,v 1.42 2020/04/21 00:01:56 cvsuser E
* http://linguscomponent.openoffice.org
* OpenOffice original - based on pspell now aspell
*
- *
* Copyright (c) 1998 - 2018, Adam Young.
* This file is part of the GRIEF Editor.
*
@@ -346,7 +345,7 @@ spell_check_buffer(LINENO start, LINENO end, int tokenize, int suggest, int uniq
for (line = start; line < end; ++line) {
LINE_t *clp;
- if (NULL != (clp = vm_lock_line(line))) {
+ if (NULL != (clp = vm_lock_line2(line))) {
const LINECHAR *text;
int length;
@@ -354,8 +353,8 @@ spell_check_buffer(LINENO start, LINENO end, int tokenize, int suggest, int uniq
lst = spell_check_string(bp, (const char *)text, length,
tokenize, suggest, line, (unique ? &wordtbl : NULL), lst, &len);
}
+ vm_unlock(line);
}
- vm_unlock(line);
}
stbl_clear(&wordtbl);
if (lst) {
@@ -1316,5 +1315,5 @@ do_spell_distance(void) /* int (string a, string b) */
ret = EditDistance(s1, s2);
acc_assign_int(ret);
}
-/*end*/
+/*end*/
diff --git a/gr/m_string.c b/gr/m_string.c
index e657c546..d396237a 100644
--- a/gr/m_string.c
+++ b/gr/m_string.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_string_c,"$Id: m_string.c,v 1.40 2020/04/21 00:01:56 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_string_c,"$Id: m_string.c,v 1.45 2021/07/12 15:55:01 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_string.c,v 1.40 2020/04/21 00:01:56 cvsuser Exp $
+/* $Id: m_string.c,v 1.45 2021/07/12 15:55:01 cvsuser Exp $
* String primitives.
*
*
@@ -27,6 +27,8 @@ __CIDENT_RCSID(gr_m_string_c,"$Id: m_string.c,v 1.40 2020/04/21 00:01:56 cvsuser
#include
#include
#include /* HUGE_VAL */
+#include "../libchartable/libchartable.h"
+#include "../libchartable/utf8.h"
#include /* str_...()/sxprintf() */
#include
@@ -50,7 +52,7 @@ static const char * x_strcasestr(const char *haystack, const char *needle);
/* Function: do_strxlen
- * Work-horse strlen() and strnlen() primitives.
+ * Workhorse strlen() and strnlen() primitives.
*
* Parameters:
* step - List step increment.
@@ -108,6 +110,56 @@ do_strxlen(int step)
}
+static accint_t
+do_wstrxlen(int step)
+{
+ accint_t len, longest = 0;
+ const LIST *lp;
+ int s;
+
+ if (isa_string(1)) {
+ return utf8len(get_str(1));
+ }
+
+ if (step <= 0) {
+ step = 1; /* default */
+ }
+
+ for (lp = get_list(1); lp && F_HALT != *lp;) {
+ switch (*lp) {
+ case F_STR:
+ case F_LIT:
+ len = (int)utf8len(LGET_PTR2(const char, lp));
+ break;
+ case F_ID: {
+ const int id = LGET_ID(lp);
+ const char *name = builtin[id].b_name;
+
+ assert(id >= 0 || (unsigned)id < builtin_count);
+ len = (int)utf8len(name);
+ }
+ break;
+ case F_RSTR:
+ len = (int)utf8len(r_ptr(LGET_PTR2(const ref_t, lp)));
+ break;
+ default:
+ len = 0;
+ break;
+ }
+
+ if (len > longest) {
+ longest = len;
+ }
+
+ for (s = 0; s < step && lp; ++s) {
+ lp = atom_next(lp);
+ }
+ }
+
+ return longest;
+}
+
+
/* Function: do_strlen
* strlen primitive - return length of string argument or length of
* longest string in a list.
@@ -155,6 +207,13 @@ do_strlen(void) /* (string|list arg, [int step = 1]) */
}
+void
+do_wstrlen(void) /* (string|list arg, [int step = 1]) */
+{
+ acc_assign_int(do_wstrxlen(get_xinteger(2, 1)));
+}
+
+
/* Function: do_strnlen
* strnlen primitive - return length of string argument or length of
* longest string in a list, limited to maxlen.
@@ -210,6 +269,16 @@ do_strnlen(void) /* (string str, int maxlen, [int step = 1]) */
}
+void
+do_wstrnlen(void) /* (string str, int maxlen, [int step = 1]) */
+{
+ const accint_t len = do_wstrxlen(get_xinteger(3, 1));
+ const accint_t maxlen = get_xinteger(2, 1);
+
+ acc_assign_int(len > maxlen ? maxlen : len);
+}
+
+
/* Function: do_atoi
* atoi primitive - string to integer
*
@@ -269,7 +338,6 @@ do_atoi(void) /* int (string str, [int svalue = TRUE]) */
}
-
/* Function: do_itoa
* itoa primitive - integer to string.
*
@@ -725,6 +793,37 @@ do_index(void) /* int (string str, int ch|string s) */
}
+void
+do_windex(void) /* int (string str, int ch|string s) */
+{
+ const char *str = get_str(1);
+ const char *cp;
+ int val = 0;
+
+ if (isa_integer(2)) { /* extension */
+ const int ch = get_xinteger(2, 0);
+
+ if (ch > 0) {
+ if (NULL != (cp = utf8chr(str, ch))) {
+ val = (cp - str) + 1;
+ }
+ }
+
+ } else {
+ const char *cp2 = get_xstr(2);
+
+ if (NULL == cp2 || 0 == *cp2) {
+ val = get_strlen(1) + 1; /* EOS */
+
+ } else if (NULL != (cp = utf8str(str, cp2))) {
+ val = (cp - str) + 1; /* character position */
+ }
+ }
+
+ acc_assign_int(val);
+}
+
+
/* Function: do_firstof
* firstof primitive - first index of character.
*
@@ -767,23 +866,50 @@ do_index(void) /* int (string str, int ch|string s) */
lastof, index, rindex
*/
void
-do_firstof(void) /* int (string str, string chars [,int &result]) */
+do_firstof(void) /* int (string str, string chars [, int &result]) */
{
- const char *start = get_str(1), *str = start,
- *end = str + get_strlen(1);
- const char *chars = get_xstr(2);
- const char *cp;
- int val = 0;
+ const char *str = get_str(1),
+ *characters = get_xstr(2), *pbrk;
+ SYMBOL *sp = get_symbol(3);
+ accint_t position = 0;
- while (str < end) {
- if (NULL != (cp = strchr(chars, *str++))) {
- val = str - start; /* starting from offset 1 */
- break;
+ if (NULL != (pbrk = strpbrk(str, characters))) {
+ position = (accint_t)((pbrk - str) + 1);
+ }
+
+ if (sp) sym_assign_int(sp, (pbrk ? *pbrk : 0));
+ acc_assign_int(position);
+}
+
+
+void
+do_wfirstof(void) /* int (string str, string chars [,int &result]) */
+{
+ const char *str = get_str(1),
+ *characters = get_xstr(2);
+ utf8_int32_t wch, wch2;
+ SYMBOL *sp = get_symbol(3);
+
+ if (characters && *characters) {
+ accint_t cursor;
+
+ for (cursor = 1; *str; ++cursor) {
+ const char *c = characters;
+
+ str = (const char *)utf8codepoint(str, &wch);
+ while (*c) {
+ c = (const char *)utf8codepoint(c, &wch2);
+ if (wch == wch2) {
+ if (sp) sym_assign_int(sp, wch);
+ acc_assign_int(cursor);
+ return;
+ }
+ }
}
}
- sym_assign_int(get_symbol(3), (val > 0 ? str[-1] : 0));
- acc_assign_int(val);
+ if (sp) sym_assign_int(sp, 0);
+ acc_assign_int(0);
}
@@ -852,6 +978,37 @@ do_rindex(void) /* int (string str, int ch|string s) */
}
+void
+do_wrindex(void) /* int (string str, int ch|string s) */
+{
+ const char *str = get_str(1);
+ const char *cp;
+ int val = 0;
+
+ if (isa_integer(2)) { /* extension 21/04/06 */
+ int ch = get_xinteger(2, 0);
+
+ if (ch > 0) {
+ if ((cp = utf8rchr(str, ch)) != NULL) {
+ val = (cp - str) + 1;
+ }
+ }
+
+ } else {
+ const char *str2 = get_str(2);
+ int len = get_strlen(2);
+
+ for (cp = str + get_strlen(1) - 1; cp >= str; --cp)
+ if (0 == utf8ncmp(cp, str2, len)) {
+ val = (cp - str) + 1;
+ break;
+ }
+ }
+
+ acc_assign_int(val);
+}
+
+
/* Function: do_lastof
* lastof primitive - last index of character.
*
@@ -899,6 +1056,7 @@ do_lastof(void) /* int (string str, string chars [,int &result])
const char *start = get_str(1),
*end = start + get_strlen(1), *str = end;
const char *chars = get_xstr(2);
+ SYMBOL *sp = get_symbol(3);
const char *cp;
int val = 0;
@@ -909,11 +1067,43 @@ do_lastof(void) /* int (string str, string chars [,int &result])
}
}
- sym_assign_int(get_symbol(3), (val > 0 ? *str : 0));
+ if (sp) sym_assign_int(sp, (val > 0 ? *str : 0));
acc_assign_int(val);
}
+void
+do_wlastof(void) /* int (string str, string chars [,int &result]) */
+{
+ const char *str = get_str(1),
+ *characters = get_xstr(2);
+ SYMBOL *sp = get_symbol(3);
+ int position = 0, character = 0;
+ utf8_int32_t wch, wch2;
+
+ if (characters && *characters) {
+ accint_t cursor;
+
+ for (cursor = 1; *str; ++cursor) {
+ const char *c = characters;
+
+ str = (const char *)utf8codepoint(str, &wch);
+ while (*c) {
+ c = (const char *)utf8codepoint(c, &wch2);
+ if (wch == wch2) {
+ character = wch;
+ position = cursor;
+ /*continue*/
+ }
+ }
+ }
+ }
+
+ if (sp) sym_assign_int(sp, character);
+ acc_assign_int(position);
+}
+
+
/* Function: do_substr
* substr primitive - retrieve a substr.
*
@@ -968,6 +1158,7 @@ do_substr(void) /* string (string str, [int offset], [int length
} else if (offset > slen) {
offset = slen;
}
+
cp = str + offset;
slen -= offset;
@@ -982,6 +1173,57 @@ do_substr(void) /* string (string str, [int offset], [int length
}
+void
+do_wsubstr(void) /* string (string str, [int offset], [int length]) */
+{ /* MCHAR */
+ const char *str = get_str(1);
+ const int slen = get_strlen(1);
+ int offset = get_xinteger(2, 1); /* non-optional?? */
+ const char *cp, *cp2, *end = str + slen;
+ int length;
+
+ if (--offset < 0) { /* index-1/TODO */
+ offset = 0;
+ } else if (offset > slen) {
+ offset = slen;
+ }
+
+ cp = str;
+ while (*cp && offset > 0) {
+ const char *cend;
+ int32_t wch;
+
+ if ((cend = charset_utf8_decode_safe(cp, end, &wch)) > cp) {
+ cp = cend;
+ --offset;
+ continue; //next
+ }
+ break; //error
+ }
+
+ if (isa_undef(3)) {
+ length = slen;
+ } else if ((length = get_xinteger(3, 0)) < 0) {
+ length = 0;
+ }
+
+ cp2 = cp;
+ while (*cp2 && length > 0) {
+ const char *cend;
+ int32_t wch;
+
+ if ((cend = charset_utf8_decode_safe(cp2, end, &wch)) > cp2) {
+ cp2 = cend;
+ --length;
+ continue; //next
+ }
+ break; //error
+ }
+
+ acc_assign_str(cp, cp2 - cp);
+}
+
+
/* Function: acc_ltrim
* Left trim the accumerlator.
*
@@ -1151,7 +1393,7 @@ do_compress(void) /* (string str, [int trim = FALSE],
Macro: trim - Chomp characters from a string.
string
- trim(string str, [string chars = " \t\r\n"])
+ trim(string str, [string chars = " \\t\\r\\n"])
Macro Description:
The 'trim()' primitive removes leading and trailing characters
@@ -1204,7 +1446,7 @@ do_trim(void) /* (string str, [string chars = NULL]) */
Macro: rtrim - Chomp characters from the end of a string.
string
- rtrim(string str, string chars = " \t\r\n")
+ rtrim(string str, string chars = \\t \\r \\n )
Macro Description:
The 'rtrim()' primitive removes trailing (or right) characters
@@ -1249,7 +1491,7 @@ do_rtrim(void) /* (string str, [string chars = NULL]) */
Macro: ltrim - Chomp characters from the front of a string.
string
- ltrim(string str, [string chars = NULL])
+ ltrim(string str, [string chars = " \\t\\r\\n"])
Macro Description:
The 'ltrim()' primitive removes leading (or left) characters
@@ -1318,7 +1560,7 @@ do_upper(void) /* (string str|int character, [TODO int capitali
if (isa_integer(1)) { /* 24/04/06 */
int ch = get_xinteger(1, 0);
- if (ch >= 'a' && ch <= 'z') { /* ASCII/MCHAR??? */
+ if (ch >= 'a' && ch <= 'z') { /* MCHAR??? */
ch = toupper(ch);
}
acc_assign_int(ch);
@@ -1331,7 +1573,7 @@ do_upper(void) /* (string str|int character, [TODO int capitali
for (; *cp; ++cp) {
const int ch = *cp;
- if (ch >= 'a' && ch <= 'z') { /* ASCII/MCHAR??? */
+ if (ch >= 'a' && ch <= 'z') { /* MCHAR??? */
*cp = (unsigned char)toupper(ch);
}
}
@@ -1339,6 +1581,20 @@ do_upper(void) /* (string str|int character, [TODO int capitali
}
+void
+do_wupper(void) /* (string str|int character, [TODO int capitalize) */
+{
+ if (isa_integer(1)) {
+ int ch = get_xinteger(1, 0);
+ acc_assign_int(utf8uprcodepoint(ch));
+
+ } else {
+ acc_assign_str(get_str(1), get_strlen(1));
+ utf8upr(acc_get_sbuf());
+ }
+}
+
+
/* Function: do_lower
* lower primitive - convert specified character or string to lower-case.
*
@@ -1379,7 +1635,7 @@ do_lower(void) /* string|int (string str|int character) */
if (isa_integer(1)) { /* 24/04/06 */
int ch = get_xinteger(1, 0);
- if (ch >= 'A' && ch <= 'Z') { /* ASCII/MCHAR??? */
+ if (ch >= 'A' && ch <= 'Z') { /* MCHAR??? */
ch = tolower(ch);
}
acc_assign_int(ch);
@@ -1393,7 +1649,7 @@ do_lower(void) /* string|int (string str|int character) */
for (; *cp; ++cp) {
const int ch = *cp;
- if (ch >= 'A' && ch <= 'Z') { /* ASCII/MCHAR??? */
+ if (ch >= 'A' && ch <= 'Z') { /* MCHAR??? */
*cp = (unsigned char)tolower(ch);
}
}
@@ -1401,6 +1657,32 @@ do_lower(void) /* string|int (string str|int character) */
}
+/*
+ Various functions provided will do case insensitive compares, or transform utf8 strings from one case to another.
+ Given the vastness of unicode, and the authors lack of understanding beyond latin codepoints on whether case means anything,
+ the following categories are the only ones that will be checked in case insensitive code:
+
+ ASCII
+ Latin-1 Supplement
+ Latin Extended-A
+ Latin Extended-B
+ Greek and Coptic
+ Cyrillic
+ */
+void
+do_wlower(void) /* string|int (string str|int character) */
+{
+ if (isa_integer(1)) {
+ int ch = get_xinteger(1, 0);
+ acc_assign_int(utf8lwrcodepoint(ch));
+
+ } else {
+ acc_assign_str(get_str(1), get_strlen(1));
+ utf8lwr(acc_get_sbuf());
+ }
+}
+
+
/* Function: isa
* Workhorse for isxxx primitive set.
*
@@ -1612,7 +1894,7 @@ do_isgold(void) /* int (string str|int character) */
const int ch = get_xinteger(1, 0);
if (ch > 0) {
- if (ch & (RANGE_FN|RANGE_KEYPAD|RANGE_MISC|RANGE_MULTIKEY|
+ if (ch & (RANGE_FUNCTION|RANGE_KEYPAD|RANGE_MISC|RANGE_MULTIKEY|
RANGE_PRIVATE|RANGE_BUTTON|RANGE_MASK)) {
ret = 1;
}
@@ -2582,6 +2864,22 @@ do_strcmp(void) /* int (string s1, string s2 [, int length]) */
}
+void
+do_wstrcmp(void) /* int (string s1, string s2 [, int length]) */
+{
+ const char *s1 = get_str(1);
+ const char *s2 = get_str(2);
+ int len = get_xinteger(3, -1);
+
+ if (len > 0) {
+ acc_assign_int(utf8ncmp(s1, s2, len));
+
+ } else {
+ acc_assign_int(utf8cmp(s1, s2));
+ }
+}
+
+
/* Function: do_strcasecmp
* strcasecmp primitive.
*
@@ -2635,6 +2933,22 @@ do_strcasecmp(void) /* (string s1, string s2 [, int length]) */
}
+void
+do_wstrcasecmp(void) /* (string s1, string s2 [, int length]) */
+{
+ const char *s1 = get_str(1);
+ const char *s2 = get_str(2);
+ int len = get_xinteger(3, -1);
+
+ if (len > 0) {
+ acc_assign_int(utf8ncasecmp(s1, s2, len));
+
+ } else {
+ acc_assign_int(utf8casecmp(s1, s2));
+ }
+}
+
+
/* Function: do_strverscmp
* strverscmp primitive.
*
@@ -2728,7 +3042,7 @@ do_strpop(void) /* (string str, [int length = 1], [int encoding]
if (rp && (used = r_used(rp)) > 0) {
/*
- * decode character value
+ * decode character value, MCHAR/???
*/
if (length >= used) {
length = used; /* trim to symbol length */
@@ -2800,6 +3114,33 @@ do_strpbrk(void) /* int (string str, string characters) */
}
+void
+do_wstrpbrk(void) /* int (string str, string characters) */
+{
+ const char *str = get_str(1),
+ *characters = get_xstr(2);
+ utf8_int32_t wch, wch2;
+
+ if (characters && *characters) { /* firstof() */
+ accint_t cursor;
+
+ for (cursor = 1; *str; ++cursor) {
+ const char *c = characters;
+
+ str = (const char *)utf8codepoint(str, &wch);
+ while (*c) {
+ c = (const char *)utf8codepoint(c, &wch2);
+ if (wch == wch2) {
+ acc_assign_int(cursor);
+ return;
+ }
+ }
+ }
+ }
+
+ acc_assign_int(0);
+}
+
/* Function: do_strstr
* strstr primitive.
@@ -2852,6 +3193,40 @@ do_strstr(void) /* int (string haystack, string needle) */
}
+void
+do_wstrstr(void) /* int (string haystack, string needle) */
+{
+ const char *haystack = get_xstr(1);
+ const char *needle = get_xstr(2);
+ accint_t position = 0;
+
+ if (haystack && needle) {
+ if (0 == *needle) { /* empty needle */
+ position = 1;
+
+ } else { /* non-empty needle */
+ utf8_int32_t t_wch;
+ accint_t cursor;
+
+ for (cursor = 1; *haystack; ++cursor) {
+ const char *h = haystack, *n = needle;
+
+ while (*h == *n && *h && *n) {
+ ++h, ++n;
+ }
+
+ if (0 == *n) { /* eon, match? */
+ position = cursor;
+ break;
+ }
+
+ haystack = (const char *)utf8codepoint(haystack, &t_wch);
+ }
+ }
+ }
+ acc_assign_int(position);
+}
+
/* Function: do_strrstr
* strrstr primitive.
@@ -2894,14 +3269,48 @@ do_strrstr(void) /* int (string haystack, string needle) */
accint_t position = 0;
if (haystack && needle) {
- const char *str;
+ if (*needle) {
+ const char *str;
+ /* initial search */
+ if (NULL != (str = strstr(haystack, needle))) {
+ position = (accint_t)((str - haystack) + 1);
- if (NULL != (str = strstr(haystack, needle))) {
- position = (accint_t)((str - haystack) + 1);
+ /* continue search */
+ while (NULL != (str = strstr(str + 1, needle))) {
+ position = (accint_t)((str - haystack) + 1);
+ }
+ }
+ }
+ }
+ acc_assign_int(position);
+}
- /* FIXME - hack implementation */
- while (NULL != (str = strstr(str + 1, needle))) {
- position = (accint_t)((str - haystack) + 1);
+
+void
+do_wstrrstr(void) /* int (string haystack, string needle) */
+{
+ const char *haystack = get_xstr(1);
+ const char *needle = get_xstr(2);
+ accint_t position = 0;
+
+ if (haystack && needle) {
+ if (*needle) { /* non-empty needle */
+ utf8_int32_t t_wch;
+ accint_t cursor;
+
+ for (cursor = 1; *haystack; ++cursor) {
+ const char *h = haystack, *n = needle;
+
+ while (*h == *n && *h && *n) {
+ ++h, ++n;
+ }
+
+ if (0 == *n) { /* eon, match? */
+ position = cursor;
+ /*continue search*/
+ }
+
+ haystack = (const char *)utf8codepoint(haystack, &t_wch);
}
}
}
@@ -3022,20 +3431,42 @@ x_strcasestr(const char *haystack, const char *needle)
A Grief extension.
*/
void
-do_characterat(void) /* int (string str, int index) */
+do_characterat(void) /* int (string str, int index, [int encoding]) */
{
const char *str = get_str(1);
int length = get_strlen(1);
accint_t position = get_xinteger(2, -1);
+/*- int encoding = (int) get_xinteger(3, -1); -*/
accint_t val = -1;
if (position > 0 && position <= length) {
- val = str[position - 1]; /* TODO/MCHAR??? */
+ val = str[position - 1];
}
acc_assign_int(val);
}
+void
+do_wcharacterat(void)
+{
+ const char *str = get_str(1);
+ accint_t position = get_xinteger(2, -1);
+
+ if (str && position > 0) {
+ utf8_int32_t wch = 0;
+ const char *next;
+ /* MCHAR */
+ for (; (next = utf8codepoint(str, &wch)) > str && wch; str = next) {
+ if (--position == 0) {
+ acc_assign_int(wch);
+ return;
+ }
+ }
+ }
+ acc_assign_int(-1);
+}
+
+
/* Function: string_mul
* Function to replicate a string 'n' times.
*
@@ -3061,4 +3492,5 @@ string_mul(const char *str, int len, int multiple)
acc_assign_strlen(i);
}
+
/*end*/
diff --git a/gr/m_string.h b/gr/m_string.h
index c38ee34c..2f7d87c4 100644
--- a/gr/m_string.h
+++ b/gr/m_string.h
@@ -1,11 +1,11 @@
#ifndef GR_M_STRING_H_INCLUDED
#define GR_M_STRING_H_INCLUDED
#include
-__CIDENT_RCSID(gr_m_string_h,"$Id: m_string.h,v 1.14 2015/07/08 21:08:15 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_string_h,"$Id: m_string.h,v 1.15 2021/06/10 06:13:02 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_string.h,v 1.14 2015/07/08 21:08:15 cvsuser Exp $
+/* $Id: m_string.h,v 1.15 2021/06/10 06:13:02 cvsuser Exp $
* String primitives.
*
*
@@ -70,8 +70,25 @@ extern void do_substr(void);
extern void do_trim(void);
extern void do_upper(void);
+extern void do_wcharacterat(void);
+extern void do_wfirstof(void);
+extern void do_windex(void);
+extern void do_wlastof(void);
+extern void do_wlower(void);
+extern void do_wrindex(void);
+extern void do_wstrcasecmp(void);
+extern void do_wstrcmp(void);
+extern void do_wstrlen(void);
+extern void do_wstrnlen(void);
+extern void do_wstrpbrk(void);
+extern void do_wstrrstr(void);
+extern void do_wstrstr(void);
+extern void do_wsubstr(void);
+extern void do_wupper(void);
+
extern void string_mul(const char *str, int len, int multipler);
__CEND_DECLS
#endif /*GR_M_STRING_H_INCLUDED*/
+
diff --git a/gr/m_terminal.c b/gr/m_terminal.c
index 9e7c7f1c..c166a0d5 100644
--- a/gr/m_terminal.c
+++ b/gr/m_terminal.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_terminal_c,"$Id: m_terminal.c,v 1.17 2020/04/21 00:01:56 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_terminal_c,"$Id: m_terminal.c,v 1.18 2021/06/22 15:52:44 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_terminal.c,v 1.17 2020/04/21 00:01:56 cvsuser Exp $
+/* $Id: m_terminal.c,v 1.18 2021/06/22 15:52:44 cvsuser Exp $
* Terminal screen and keyboard primitives.
*
*
@@ -173,8 +173,7 @@ static struct pt_map pt_features[] = {
{ TF_VT_DAVERSION, PT_MKINT(x_pt.pt_vtdaversion), "vt_daversion" },
{ TF_ENCODING, PT_MKSTR(x_pt.pt_encoding), "encoding" },
- { TF_UNICODE_VERSION, PT_MKINT(x_pt.pt_unicode_version), "unicode_version" },
- { TF_UNICODE_WIDTH, PT_MKINT(x_pt.pt_unicode_width), "unicode_width" },
+ { TF_UNICODE_VERSION, PT_MKSTR(x_pt.pt_unicode_version), "unicode_version" },
{ -2, 0, NULL, 0, "" }
};
@@ -538,9 +537,8 @@ do_set_term_characters(void) /* int ([int ident string desc], [string|int] va
! TF_ENCODING encoding String Terminal character encoding.
- ! TF_UNICODE_VERSION unicode_version Integer UNICODE interface version.
-
- ! TF_UNICODE_WIDTH unicode_width Integer UNICODE character width.
+ ! TF_UNICODE_VERSION unicode_version String UNICODE interface version, for
+ example "6.0.1".
(end table)
TF_ATTRIBUTE:
diff --git a/gr/m_window.c b/gr/m_window.c
index 7d8151a2..d7886f14 100644
--- a/gr/m_window.c
+++ b/gr/m_window.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_m_window_c,"$Id: m_window.c,v 1.25 2020/06/03 16:22:53 cvsuser Exp $")
+__CIDENT_RCSID(gr_m_window_c,"$Id: m_window.c,v 1.28 2021/10/18 13:09:48 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: m_window.c,v 1.25 2020/06/03 16:22:53 cvsuser Exp $
+/* $Id: m_window.c,v 1.28 2021/10/18 13:09:48 cvsuser Exp $
* Window primitives.
*
*
@@ -19,6 +19,8 @@ __CIDENT_RCSID(gr_m_window_c,"$Id: m_window.c,v 1.25 2020/06/03 16:22:53 cvsuser
*/
#include
+#include "../libchartable/libchartable.h"
+#include "../libwidechar/widechar.h"
#include /* str_...()/sxprintf() */
#include "m_window.h" /* public interface */
@@ -1288,8 +1290,8 @@ do_change_window_pos(void) /* ([int x], [int y], [int w], [int h], [int win
x = vtcols - 1;
}
- w1 = (wp->w_message ? strlen(wp->w_message) : 0) + 4;
- w2 = (wp->w_title ? strlen(wp->w_title) : 0) + 4;
+ w1 = (wp->w_message ? utf8_swidth(wp->w_message) : 0) + 4; /*MCHAR*/
+ w2 = (wp->w_title ? utf8_swidth(wp->w_title) : 0) + 4;
if (w < w1) w = w1;
if (w < w2) w = w2;
@@ -1456,8 +1458,7 @@ do_set_window(void) /* ([int winnum]) */
curwp->w_status |= WFHARD;
}
wp->w_status |= WFHARD;
- curwp = wp;
- set_hooked();
+ set_curwp(wp);
ret = 1;
}
acc_assign_int(ret);
@@ -1577,8 +1578,7 @@ do_delete_window(void) /* void ([int winnum]) */
return;
if (wp == curwp) {
- curwp = &x_window_null;
- set_hooked();
+ set_curwp(&x_window_null);
}
ismenu = (W_MENU == wp->w_type);
diff --git a/gr/mac1.c b/gr/mac1.c
index 504d706d..c58e018f 100644
--- a/gr/mac1.c
+++ b/gr/mac1.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_mac1_c,"$Id: mac1.c,v 1.70 2020/04/21 00:01:57 cvsuser Exp $")
+__CIDENT_RCSID(gr_mac1_c,"$Id: mac1.c,v 1.75 2021/10/18 13:07:25 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: mac1.c,v 1.70 2020/04/21 00:01:57 cvsuser Exp $
+/* $Id: mac1.c,v 1.75 2021/10/18 13:07:25 cvsuser Exp $
* Basic primitives.
*
*
@@ -369,12 +369,13 @@ do_delete_to_eol(void) /* void () */
LINE_t *lp;
int dot, n;
- lp = linep(cline);
- dot = line_offset2(lp, cline, ccol, LOFFSET_NORMAL);
- if ((n = llength(lp) - dot) > 0) {
- ldelete(n);
+ if (NULL != (lp = vm_lock_line2(cline))) {
+ dot = line_offset_const(lp, cline, ccol, LOFFSET_NORMAL);
+ if ((n = llength(lp) - dot) > 0) {
+ ldelete(n);
+ }
+ vm_unlock(cline);
}
- vm_unlock(cline);
}
@@ -417,10 +418,11 @@ do_delete_line(void) /* void () */
u_dot();
*cur_col = 1;
- lp = linep(cline);
- ldelete(llength(lp) + 1); /* MCHAR, line plus EOL */
+ if (NULL != (lp = vm_lock_line2(cline))) {
+ ldelete(llength(lp) + 1); /* MCHAR, line plus EOL */
+ vm_unlock(cline);
+ }
*cur_col = ccol;
- vm_unlock(cline);
}
@@ -1758,15 +1760,15 @@ do_redraw(void) /* ([int winch]) */
Macro: insert - Insert string into current buffer.
int
- insert(string str, [int num = 1])
+ insert(string|int val, [int num = 1])
Macro Description:
- The 'insert()' primitive inserts the specified string 'str'
- into the current buffer. The string shall be inserted 'num'
- times, which if omitted defaults to 1.
+ The 'insert_process()' primitive inserts the specified string or
+ integer character value 'val' into the current buffer. The value
+ shall be inserted 'num' times, which if omitted defaults to 1.
Macro Parameters:
- str - String value to be inserted.
+ val - String or integer character value to be inserted.
num - Option integer number stating the repeat count, if
specified then the string is inserted the given number of
@@ -1787,16 +1789,16 @@ do_redraw(void) /* ([int winch]) */
Macro: insert_process - Send string to a attached process.
int
- insert_process(string str, [int num = 1])
+ insert_process(string|int val, [int num = 1])
Macro Description:
- The 'insert_process()' primitive inserts the specified string
- 'str' into the process attached to the current buffer. The
- string shall be inserted 'num' times, which if omitted
- defaults to 1.
+ The 'insert_process()' primitive inserts the specified string or
+ integer character value 'val' into the process attached to the
+ current buffer. The value shall be inserted 'num' times, which
+ if omitted defaults to 1.
Macro Parameters:
- str - String value to be inserted.
+ val - String or integer character value to be inserted.
num - Option integer number stating the repeat count, if
specified then the string is inserted the given number
@@ -1813,7 +1815,7 @@ do_redraw(void) /* ([int winch]) */
insert, insertf, insert_buffer, insert_process
*/
void
-do_insert(int proc) /* int (string str, [int num]) */
+do_insert(int proc) /* int (string str | int character, [int num]) */
{
const char *cp;
accint_t num;
@@ -1842,6 +1844,7 @@ do_insert(int proc) /* int (string str, [int num]) */
/*
* Otherwise insert the specified string
+ * MCHAR/??? utf8->iconv
*/
cp = get_str(1);
len = (int)strlen(cp);
@@ -1912,17 +1915,18 @@ void
do_insertf(void) /* int (string fmt, ...) */
{
const char *cp;
- int len = 0;
+ int len = 0, width = 0;
if (margc > 1) {
- cp = print_formatted(0, &len); /* sprintf style output */
+ cp = print_formatted(0, &len, &width); /* sprintf style output */
} else {
cp = get_str(1);
+ len = width = get_strlen(1);
}
if (cp) {
linserts(cp, len);
}
- acc_assign_int(len);
+ acc_assign_int(width);
}
@@ -1989,7 +1993,7 @@ do_insert_buffer(void) /* int (int bufnum, string | expr ....) */
{
BUFFER_t *bp;
const char *cp;
- int len = 0;
+ int len = 0, width = 0;
if (NULL == (bp = buf_lookup(get_xinteger(1, -1)))) {
ewprintf("insert_buffer: no such buffer");
@@ -1998,23 +2002,22 @@ do_insert_buffer(void) /* int (int bufnum, string | expr ....) */
}
if (margc > 2) {
- cp = print_formatted(1, &len); /* sprintf style output */
+ cp = print_formatted(1, &len, &width); /* sprintf style output */
} else {
cp = get_str(2); /* just quote string */
+ len = width = get_strlen(2);
}
if (cp) {
- BUFFER_t *saved_bp = curbp;
+ BUFFER_t *ocurbp = curbp;
if (bp != curbp) {
- curbp = bp;
- set_hooked();
+ set_curbp(bp);
}
linserts(cp, len);
- curbp = saved_bp;
- set_hooked();
+ set_curbp(ocurbp);
}
- acc_assign_int(len);
+ acc_assign_int(width);
}
@@ -2503,7 +2506,7 @@ void
do_read(void) /* string ([int number], [int &status]) */
{
const LINENO cline = *cur_line, ccol = *cur_col;
- int status = 0; /* extension, status being -1=eof,1=eol,0=partial */
+ int status = 1; /* extension, status being -1=eof,1=eol,0=partial */
LINE_t *lp;
if (NULL == (lp = vm_lock_linex(curbp, cline))) {
@@ -2514,12 +2517,9 @@ do_read(void) /* string ([int number], [int &status]) */
} else {
int dot, len, copy;
- dot = line_offset2(lp, cline, ccol, LOFFSET_NORMAL);
+ dot = line_offset_const(lp, cline, ccol, LOFFSET_NORMAL);
len = llength(lp) - dot;
- trace_ilog("read(line:%d,col:%d,dot:%d,length:%d) : %d\n", \
- (int)cline, (int)ccol, dot, llength(lp), len);
-
if (isa_undef(1)) {
copy = len; /* EOL */
@@ -2530,15 +2530,51 @@ do_read(void) /* string ([int number], [int &status]) */
copy = (value1 > len ? len : value1);
}
+ trace_ilog("read(line:%d,col:%d,dot:%d,length:%d) : %d of %d\n", \
+ (int)cline, (int)ccol, dot, llength(lp), copy, len);
+
+ // MCHAR/???, iconv->utf8
if (copy <= 0) {
acc_assign_str("\n", 1); /* empty line */
- } else if (copy < len) { /* sub-line */
- acc_assign_str((const char *) ltext(lp) + dot, copy);
- status = 0;
+ } else {
+ const LINECHAR *start = ltext(lp) + dot;
+
+ if (! BFTST(curbp, BF_BINARY)) { /* MCHAR */
+ const LINECHAR *cp = start,
+ *end = ltext(lp) + llength(lp);
+
+ if (copy >= len) {
+ cp = end;
+ } else {
+ LINENO pos = ccol;
+ int32_t ch;
+
+ while (copy > 0 && cp < end) {
+ int length, width =
+ character_decode(pos, cp, end, &length, &ch, NULL);
+ if (width > 0) --copy;
+ pos += width;
+ cp += length;
+ }
+ }
+
+ if (cp >= end) { /* EOL + \n */
+ acc_assign_str2((const char *) start, len, "\n", 1);
+ } else { /* partial */
+ acc_assign_str((const char *) start, cp - start);
+ status = 0;
+ }
+
+ } else {
+ if (copy >= len) { /* EOL + \n */
+ acc_assign_str2((const char *) start, copy, "\n", 1);
- } else { /* copied to EOL, must add \n */
- acc_assign_str2((const char *) ltext(lp) + dot, copy, "\n", 1);
+ } else { /* partial */
+ acc_assign_str((const char *) start, copy);
+ status = 0;
+ }
+ }
}
vm_unlock(cline);
@@ -2670,4 +2706,4 @@ do_input_mode(void) /* int (int char, int flag) */
acc_assign_int((accint_t)sys_enable_char(ch, value));
}
-/*end*/
\ No newline at end of file
+/*end*/
diff --git a/gr/main.h b/gr/main.h
index d8274001..74046f4c 100644
--- a/gr/main.h
+++ b/gr/main.h
@@ -1,11 +1,11 @@
#ifndef GR_MAIN_H_INCLUDED
#define GR_MAIN_H_INCLUDED
#include
-__CIDENT_RCSID(gr_main_h,"$Id: main.h,v 1.28 2020/05/03 21:10:56 cvsuser Exp $")
+__CIDENT_RCSID(gr_main_h,"$Id: main.h,v 1.29 2021/10/17 12:12:23 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: main.h,v 1.28 2020/05/03 21:10:56 cvsuser Exp $
+/* $Id: main.h,v 1.29 2021/10/17 12:12:23 cvsuser Exp $
* Globals and main process primitives.
*
*
@@ -119,6 +119,10 @@ extern uint32_t xf_test; /* TRUE enables test code --- in
extern BUFFER_t * curbp; /* Current buffer */
extern WINDOW_t * curwp; /* Current window */
+extern void set_curbp(BUFFER_t *bp);
+extern void set_curwp(WINDOW_t *wp);
+extern void set_curwpbp(WINDOW_t *wp, BUFFER_t *bp);
+
extern void panic(const char *msg, ...) __ATTRIBUTE_FORMAT__((printf, 1, 2));
extern void gr_exit(int);
@@ -132,4 +136,4 @@ extern void do_suspend(void);
__CEND_DECLS
-#endif /*GR_MAIN_H_INCLUDED*/
\ No newline at end of file
+#endif /*GR_MAIN_H_INCLUDED*/
diff --git a/gr/map.c b/gr/map.c
index df536780..d0496738 100644
--- a/gr/map.c
+++ b/gr/map.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_map_c,"$Id: map.c,v 1.32 2015/02/11 23:25:13 cvsuser Exp $")
+__CIDENT_RCSID(gr_map_c,"$Id: map.c,v 1.34 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: map.c,v 1.32 2015/02/11 23:25:13 cvsuser Exp $
+/* $Id: map.c,v 1.34 2021/07/05 15:01:27 cvsuser Exp $
* High-level character mapping functionality.
*
*
@@ -86,7 +86,7 @@ character_decode(int pos, const LINECHAR *cp, const LINECHAR *end, int *lenp, in
if ((wcp = iconv->ic_decode(iconv, cp, end, &ch, &wraw)) > cp) {
length = wcp - cp;
if (ch > 0xff) { /* wide character, FIXME - iconv() specific?? */
- width = vtcharwidth(ch, mchar_ucs_width(ch, 1));
+ width = vtcharwidth(ch, Wcwidth(ch));
*lenp = length;
if (rawp) *rawp = wraw;
*chp = ch;
@@ -187,13 +187,25 @@ esccombined2: while (escend < end) { /* find escape-sequence */
}
+const LINE_t *
+linep0(LINENO line)
+{
+ LINE_t *lp;
+
+ if (NULL == curbp || NULL == (lp = linepx(curbp, line))) {
+ return x_static_line; /* XXX/FIXME- replace with linep2 */
+ }
+ return lp;
+}
+
+
LINE_t *
-linep(LINENO line)
+linep2(LINENO line)
{
LINE_t *lp;
if (NULL == curbp || NULL == (lp = linepx(curbp, line))) {
- return x_static_line; /* XXX - yuk, buffer specific or NULL? */
+ return NULL;
}
return lp;
}
@@ -339,13 +351,13 @@ line_sizeregion(const LINE_t *lp, int col, int dot, int characters, LINENO *leng
while (count < characters && cp < end) {
int32_t t_ch;
- int t_length,t_width =
+ int t_length, t_width =
character_decode(col, cp, end, &t_length, &t_ch, NULL);
#if defined(DO_TRACE_CHARACTER)
trace_character(t_ch, t_width, cp, t_length);
#endif
- cp += t_length;
+ cp += t_length;
length += t_length;
col += t_width;
@@ -436,12 +448,12 @@ line_current_offset(int fill)
int
line_offset(const int line, const int col, int fill)
{
- int offset = 0;
+ int dot = 0;
LINE_t *lp;
if (curbp) {
if (NULL != (lp = vm_lock_linex(curbp, line))) {
- offset = line_offset2(lp, line, col, fill);
+ dot = line_offset_fill(lp, line, col, fill);
vm_unlock(line);
} else {
curbp->b_vline = line;
@@ -452,11 +464,11 @@ line_offset(const int line, const int col, int fill)
curbp->b_vwidth = 0;
}
}
- return offset;
+ return dot;
}
-/* Function: line_offset2
+/* Function: line_offset_fill
* Convert the specified 'column' position into an physical byte offset from the start
* of the current line.
*
@@ -474,7 +486,7 @@ line_offset(const int line, const int col, int fill)
* No fill, returning complete character include leading colorization.
*
* LOFFSET_LASTBYTE -
- * No fill, return offset last byte within the character including are
+ * No fill, return offset last byte within the character including any
* combined characters.
*
* LOFFSET_NORMAL -
@@ -494,26 +506,21 @@ line_offset(const int line, const int col, int fill)
* Line Offset.
*/
int
-line_offset2(LINE_t *lp, const int line, const int col, int fill)
+line_offset_fill(LINE_t *lp, const int line, const int col, int fill)
{
-// const int isuc = buf_isuc(curbp); // UNICCODE
const int isutf8 = buf_isutf8(curbp); /* buffer encoding */
- int used, length = 0, width = 0;
- const LINECHAR *cp, *start, *end;
- int vstatus = 0, pos = 1, offset = 0;
+ const LINECHAR *start = ltext(lp),
+ *cp = start, *end = cp + llength(lp);
+ int length = 0, width = 0;
+ int pos = 1, offset = 0;
+ int vstatus = 0;
int32_t ch = 0;
- start = ltext(lp);
- used = llength(lp);
-
- cp = start;
- end = start + used;
-
- ED_ITRACE(("line_offset(line:%d, col:%d, fill:%d, used:%d)\n", line, col, fill, used))
-
assert(col >= 1);
assert(fill >= LOFFSET_LASTBYTE && fill <= LOFFSET_FILL_SPACE);
+ ED_ITRACE(("line_offset(line:%d, col:%d, fill:%d, used:%d)\n", line, col, fill, llength(lp)))
+
if (col <= 0) {
offset = 0;
goto done;
@@ -570,6 +577,7 @@ line_offset2(LINE_t *lp, const int line, const int col, int fill)
if (t_width || t_ch <= 0xff || t_length <= 0) {
break; /* not combining character */
}
+
#if defined(DO_TRACE_CHARACTER)
trace_character(t_ch, t_width, cp, t_length);
#endif
@@ -671,6 +679,7 @@ line_offset2(LINE_t *lp, const int line, const int col, int fill)
if (t_ch != t_raw) {
vstatus |= BUFFERVSTATUS_ILLEGAL;
}
+
if (0 == combined) {
curbp->b_vwidth = t_width;
}
@@ -766,6 +775,14 @@ done:;
}
+int
+line_offset_const(const LINE_t *lp, const int line, const int col, int fill)
+{
+ assert(fill >= LOFFSET_LASTBYTE && fill <= LOFFSET_NORMAL_MATCH);
+ return line_offset_fill((LINE_t *)lp, line, col, fill);
+}
+
+
static __CINLINE int
istab(const LINECHAR ch)
{
@@ -916,9 +933,9 @@ int
line_column_eol(int line)
{
int column = 0;
- LINE_t *lp;
+ const LINE_t *lp;
- if (NULL != (lp = vm_lock_line(line))) {
+ if (NULL != (lp = vm_lock_line2(line))) {
column = line_column2(lp, line, llength(lp));
vm_unlock(line);
}
@@ -930,9 +947,9 @@ int
line_column(const int line, int offset)
{
int column = 0;
- LINE_t *lp;
+ const LINE_t *lp;
- if (NULL != (lp = vm_lock_line(line))) {
+ if (NULL != (lp = vm_lock_line2(line))) {
column = line_column2(lp, line, offset);
vm_unlock(line);
}
@@ -1007,8 +1024,8 @@ line_tab_backfill(void)
ED_TRACE2(("tab_backfill(line:%d,col:%d)\n", cline, ccol))
- lp = vm_lock_line(cline);
- if (! ledit(lp, 0)) {
+ lp = vm_lock_line2(cline);
+ if (NULL == lp || !ledit(lp, 0)) {
vm_unlock(cline);
return;
}
@@ -1070,4 +1087,5 @@ line_tab_backfill(void)
vm_unlock(cline);
}
+
/*end*/
diff --git a/gr/map.h b/gr/map.h
index 341e76b4..df018621 100644
--- a/gr/map.h
+++ b/gr/map.h
@@ -1,11 +1,11 @@
#ifndef GR_MAP_H_INCLUDED
#define GR_MAP_H_INCLUDED
#include
-__CIDENT_RCSID(gr_map_h,"$Id: map.h,v 1.14 2014/10/22 02:33:13 ayoung Exp $")
+__CIDENT_RCSID(gr_map_h,"$Id: map.h,v 1.15 2021/06/10 06:13:02 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: map.h,v 1.14 2014/10/22 02:33:13 ayoung Exp $
+/* $Id: map.h,v 1.15 2021/06/10 06:13:02 cvsuser Exp $
* Character/line mapping ulitlies.
*
*
@@ -25,7 +25,8 @@ __CPRAGMA_ONCE
__CBEGIN_DECLS
-#define vm_lock_line(__ln) linep(__ln)
+#define vm_lock_line(__ln) linep0(__ln)
+#define vm_lock_line2(__ln) linep2(__ln)
#define vm_lock_linex(__bp,__ln) \
linepx(__bp, __ln)
#define vm_unlock(__ln)
@@ -42,14 +43,15 @@ enum {
LOFFSET_LASTBYTE =-2, /* last byte, including ESC/combined */
LOFFSET_FIRSTBYTE =-1, /* first byte */
LOFFSET_NORMAL =0, /* first normal character roffset */
- LOFFSET_NORMAL_MATCH =1, /* first normal and match cursor on completion */
+ LOFFSET_NORMAL_MATCH =1, /* first normal and match/update cursor on completion */
LOFFSET_FILL_VSPACE =2, /* fill virtual-space and EOL */
LOFFSET_FILL_SPACE =3 /* fill virtual-space, tabs and EOL */
};
extern int character_decode(int pos, const LINECHAR *cp, const LINECHAR *end, int *lengthp, int32_t *chp, int32_t *rawp);
-extern LINE_t * linep(LINENO line);
+extern const LINE_t * linep0(LINENO line);
+extern LINE_t * linep2(LINENO line);
extern LINE_t * linepx(BUFFER_t *bp, LINENO line);
extern void linep_flush(BUFFER_t *bp);
@@ -59,7 +61,8 @@ extern int line_current_status(int *value, int count);
extern int line_current_offset(int fill);
extern int line_offset(const int line, const int col, int fill);
-extern int line_offset2(LINE_t *lp, const int line, const int col, int fill);
+extern int line_offset_const(const LINE_t *lp, const int line, const int col, int fill);
+extern int line_offset_fill(LINE_t *lp, const int line, const int col, int fill);
extern int line_current_column(int offset);
extern int line_column_eol(int line);
diff --git a/gr/mchar.h b/gr/mchar.h
index a53e54a9..6e4dfa11 100644
--- a/gr/mchar.h
+++ b/gr/mchar.h
@@ -1,11 +1,11 @@
#ifndef GR_MCHAR_H_INCLUDED
#define GR_MCHAR_H_INCLUDED
#include
-__CIDENT_RCSID(gr_mchar_h,"$Id: mchar.h,v 1.15 2014/10/22 02:33:13 ayoung Exp $")
+__CIDENT_RCSID(gr_mchar_h,"$Id: mchar.h,v 1.17 2021/07/05 15:01:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: mchar.h,v 1.15 2014/10/22 02:33:13 ayoung Exp $
+/* $Id: mchar.h,v 1.17 2021/07/05 15:01:27 cvsuser Exp $
* Multibyte character support.
*
*
@@ -23,6 +23,9 @@ __CPRAGMA_ONCE
#include
+#include "../libchartable/libchartable.h"
+#include "../libwidechar/widechar.h"
+
__CBEGIN_DECLS
#define MCHAR_MAX_ENCODING 48
@@ -163,7 +166,8 @@ extern char * mchar_guess_default(void);
extern const mcharcharsetinfo_t *
mchar_info(mcharcharsetinfo_t *info, const char *name, int namelen);
-
+
+extern void mchar_iconv_init(void);
extern mchar_iconv_t * mchar_iconv_open(const char *encoding);
extern void mchar_iconv_close(mchar_iconv_t *iconv);
#define mchar_encoding(__ic) \
@@ -179,9 +183,6 @@ extern void mchar_iconv_close(mchar_iconv_t *iconv);
#define mchar_length(__ic, __ch) \
((* (__ic)->ic_length)(__ic, __ch))
-extern int mchar_ucs_width(int32_t ch, int bad);
-extern int mchar_ucs_encode(int32_t ch, char *buffer);
-
extern mchar_istream_t * mchar_stream_open(mchar_iconv_t *ic, int handle, const char *filename, const char *mode);
extern void mchar_stream_push(mchar_istream_t *is, const char *buffer, size_t buflen);
extern size_t mchar_stream_read(mchar_istream_t *is, char *buffer, size_t buflen, size_t *inbytes);
diff --git a/gr/mchar_guess.c b/gr/mchar_guess.c
index 59dd1e99..a6c152fc 100644
--- a/gr/mchar_guess.c
+++ b/gr/mchar_guess.c
@@ -1,12 +1,12 @@
#include
-__CIDENT_RCSID(gr_mchar_guess_c,"$Id: mchar_guess.c,v 1.27 2020/06/05 23:13:47 cvsuser Exp $")
+__CIDENT_RCSID(gr_mchar_guess_c,"$Id: mchar_guess.c,v 1.29 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: mchar_guess.c,v 1.27 2020/06/05 23:13:47 cvsuser Exp $
+/* $Id: mchar_guess.c,v 1.29 2021/07/05 15:01:27 cvsuser Exp $
* Character-set conversion/file type guess logic.
*
*
- * Copyright (c) 1998 - 2018, Adam Young.
+ * Copyright (c) 1998 - 2021, Adam Young.
* This file is part of the GRIEF Editor.
*
* The GRIEF Editor is free software: you can redistribute it
@@ -191,10 +191,10 @@ static const struct guessdecoder {
* guess - Guesser (libguess).
* enca - Extremely Naive Charset Analyser (libenca).
*
- * Note, order is some-what important as the MBCS checks can result in
+ * Note, order is some-what important as the MBCS checks can result in
* false positives, as such are generally last in line.
*
- * Module usage has evolved over time, with a number being pure
+ * Module usage has evolved over time, with a number being pure
* experimental alternatives.
*/
{ NAME("mark"), guess_marker, GUESS_FDEFAULT },
@@ -1065,8 +1065,8 @@ guess_guess(guessinfo_t *guess, const void *buffer, unsigned length)
* European languages, and a few Unicode variants, independently
* on language.
*
- * Currently it supports Belarusian, Bulgarian, Croatian, Czech,
- * Estonian, Hungarian, Latvian, Lithuanian, Polish, Russian,
+ * Currently it supports Belarusian, Bulgarian, Croatian, Czech,
+ * Estonian, Hungarian, Latvian, Lithuanian, Polish, Russian,
* Slovak, Slovene, Ukrainian, Chinese, and some multibyte
* encodings independently on language.
*
@@ -1076,8 +1076,8 @@ guess_guess(guessinfo_t *guess, const void *buffer, unsigned length)
* length - Length of the buffer.
*
* Warning:
- * libenca is licensed under the GPLv2; the user *must* explicitly
- * build a local non-standard version and agree to *never* to
+ * libenca is licensed under the GPLv2; the user *must* explicitly
+ * build a local non-standard version and agree to *never* to
* release.
*
* References:
@@ -1737,8 +1737,9 @@ guess_utf8(guessinfo_t *guess, const void *buffer, unsigned length)
guessterm_t linebreak = {0};
register const unsigned char *cursor = buffer;
const unsigned char *end = cursor + (length - 1);
- int nonascii = 0, isutf8 = 0;
- int32_t raw, ch = 0;
+ unsigned nonascii = 0, noutf8 = 0;
+ int isutf8 = 0;
+ int32_t ch = 0;
if (BFTYP_UNKNOWN == bomtype || BFTYP_UTF8 == bomtype) {
@@ -1749,24 +1750,31 @@ guess_utf8(guessinfo_t *guess, const void *buffer, unsigned length)
while (cursor < end && isutf8 >= 0) {
if ((ch = *cursor++) >= 0x80) {
- if (NULL == (cursor = charset_utf8_decode(cursor - 1, end, &ch, &raw)) || ch != raw) {
+ /*
+ * utf8, allowing illegal and overlong only rejecting illformed.
+ */
+ cursor = charset_utf8_decode(cursor - 1, end, &ch);
+ if (ch <= 0) {
trace_ilog("\t\t==> bad UTF8\n");
- isutf8 = -1;
- break;
+ if (++noutf8 > (length/1)) { /* non utf8 >1% */
+ isutf8 = -1;
+ break;
+ }
+ continue;
}
isutf8 = 1;
}
if (ch <= 0xff) {
/*
- * [0x0A], [0x0D], [0x20 - 0x7F], [0x85], [0xA0 - 0xFF]
- */
+ * [CR/LF], [BS], [FF], [0x20 - 0x7F], [0x85], [0xA0 - 0xFF]
+ */
if (0 == (x_charflags[ch] & (A|X|I))) {
trace_ilog("\t\t==> non ASCII (%d/0x%02x)\n", ch, ch);
- if (++nonascii > 2) {
- isutf8 = -1; /* neither ASCII nor Latin1 */
+ if (++nonascii > 2) { /* neither ASCII nor Latin1 */
+ isutf8 = -1;
}
- } else {
+ } else {
linetally(&linebreak, ch);
}
}
@@ -1935,7 +1943,7 @@ guess_gb18030(guessinfo_t *guess, const void *buffer, unsigned length)
const unsigned char *cursor = (const unsigned char *)buffer,
*end = cursor + length;
int isgb = 0;
-
+
while (cursor < end && isgb >= 0) {
const unsigned char c1 = *cursor++;
@@ -2203,4 +2211,5 @@ guess_ebcdic(guessinfo_t *guess, const void *buffer, unsigned length)
#endif
return 0;
}
+
/*end*/
diff --git a/gr/mchar_iconv.c b/gr/mchar_iconv.c
index e3c9d335..d06a7c99 100644
--- a/gr/mchar_iconv.c
+++ b/gr/mchar_iconv.c
@@ -1,12 +1,12 @@
#include
-__CIDENT_RCSID(gr_mchar_iconv_c,"$Id: mchar_iconv.c,v 1.22 2018/10/01 20:59:48 cvsuser Exp $")
+__CIDENT_RCSID(gr_mchar_iconv_c,"$Id: mchar_iconv.c,v 1.24 2021/06/19 09:41:55 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: mchar_iconv.c,v 1.22 2018/10/01 20:59:48 cvsuser Exp $
+/* $Id: mchar_iconv.c,v 1.24 2021/06/19 09:41:55 cvsuser Exp $
* Character-set conversion/mapping interface and adapters.
*
*
- * Copyright (c) 1998 - 2018, Adam Young.
+ * Copyright (c) 1998 - 2021, Adam Young.
* This file is part of the GRIEF Editor.
*
* The GRIEF Editor is free software: you can redistribute it
@@ -124,8 +124,6 @@ static mchar_istream_t * icnv_stream_open(struct mchar_iconv *ic, int fd,
static void icnv_stream_close(mchar_iconv_t *ic, mchar_istream_t *is);
#endif
-extern void charset_iconv_init(void); /* FIXME/XXX */
-
static mchar_iconv_t x_iconv_internal[] = {
{ 0, "binary", 1,
uchar_decode,
@@ -166,6 +164,21 @@ static mchar_iconv_t x_iconv_internal[] = {
};
+/* Function: mchar_iconv_init
+ * Run-time initialisation
+ *
+ */
+void
+mchar_iconv_init(void)
+{
+#if defined(_WIN32) && defined(WIN32_DYNAMIC_ICONV)
+#if defined(HAVE_LIBICONV_CITRUS_DLL)
+ w32_iconv_dllname(HAVE_LIBICONV_CITRUS_DLL);
+#endif
+#endif
+}
+
+
/* Function: mchar_iconv_open
* Open a conversion session, allowing conversion between an external encoding and Unicode.
*
@@ -459,7 +472,7 @@ static const void *
utf8_decode(mchar_iconv_t *ic, const void *src, const void *cpend, int32_t *cooked, int32_t *raw)
{
__CUNUSED(ic)
- return charset_utf8_decode(src, cpend, cooked, raw);
+ return charset_utf8_decode_cook(src, cpend, cooked, raw);
}
@@ -934,10 +947,10 @@ icnv_open(const char *encoding)
mchar_iconv_t *ic;
if (encoding) strxcpy(toencoding, encoding, sizeof(toencoding));
- strxcat(toencoding, " //TRANSLIT", sizeof(toencoding));
+ strxcat(toencoding, "//TRANSLIT", sizeof(toencoding));
if (NULL == (ic = chk_alloc(sizeof(mchar_iconv_t) + encodinglen)) ||
- ICONV_NULL == (ihandle = my_iconv_open("utf-8 //IGNORE", encoding)) ||
+ ICONV_NULL == (ihandle = my_iconv_open("utf-8//TRANSLIT", encoding)) || /*IGNORE or TRANSLIT?*/
ICONV_NULL == (ohandle = my_iconv_open(toencoding, "utf-8"))) {
if (ic) {
if (ICONV_NULL != ihandle) {
diff --git a/gr/mchar_info.c b/gr/mchar_info.c
index 23679bec..6e14af18 100644
--- a/gr/mchar_info.c
+++ b/gr/mchar_info.c
@@ -1,12 +1,12 @@
#include
-__CIDENT_RCSID(gr_mchar_info_c,"$Id: mchar_info.c,v 1.19 2018/10/01 20:59:48 cvsuser Exp $")
+__CIDENT_RCSID(gr_mchar_info_c,"$Id: mchar_info.c,v 1.20 2021/06/13 16:28:51 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: mchar_info.c,v 1.19 2018/10/01 20:59:48 cvsuser Exp $
+/* $Id: mchar_info.c,v 1.20 2021/06/13 16:28:51 cvsuser Exp $
* Locale/multibyte character information.
*
*
- * Copyright (c) 1998 - 2018, Adam Young.
+ * Copyright (c) 1998 - 2021, Adam Young.
* This file is part of the GRIEF Editor.
*
* The GRIEF Editor is free software: you can redistribute it
@@ -253,7 +253,7 @@ mchar_info_init(void)
* GRPATH/charset.alias
*/
charset_alias_init();
- mchar_alias_load(CHARSET_MODE_INI, "crcharset.list");
+ mchar_alias_load(CHARSET_MODE_INI, "grcharset.list");
mchar_alias_load(CHARSET_MODE_X11, "charset.alias");
return 0;
}
@@ -607,5 +607,5 @@ charset_map(const char *name, int namelen)
}
return NULL;
}
-/*end*/
+/*end*/
diff --git a/gr/mchar_util.c b/gr/mchar_util.c
index 7b8acc66..7ef22223 100644
--- a/gr/mchar_util.c
+++ b/gr/mchar_util.c
@@ -1,12 +1,12 @@
#include
-__CIDENT_RCSID(gr_mchar_util_c,"$Id: mchar_util.c,v 1.17 2018/10/01 20:59:48 cvsuser Exp $")
+__CIDENT_RCSID(gr_mchar_util_c,"$Id: mchar_util.c,v 1.19 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: mchar_util.c,v 1.17 2018/10/01 20:59:48 cvsuser Exp $
+/* $Id: mchar_util.c,v 1.19 2021/07/05 15:01:27 cvsuser Exp $
* Locale/multibyte character utility functionality.
*
*
- * Copyright (c) 1998 - 2018, Adam Young.
+ * Copyright (c) 1998 - 2021, Adam Young.
* This file is part of the GRIEF Editor.
*
* The GRIEF Editor is free software: you can redistribute it
@@ -31,32 +31,6 @@ __CIDENT_RCSID(gr_mchar_util_c,"$Id: mchar_util.c,v 1.17 2018/10/01 20:59:48 cvs
#include
#include "mchar.h" /* mchar_...() */
-#include "../libchartable/libchartable.h"
-
-
-/* Function: mchar_ucs_width
- * Retrieve the character width of the specified Unicode character.
- *
- * Parameters:
- * ch - Character value.
- *
- * bad - Method of evaluating invalid character values.
- *
- * Returns:
- * Character width.
- */
-int
-mchar_ucs_width(int32_t ch, int bad)
-{
- return charset_width_ucs(ch, bad);
-}
-
-
-int
-mchar_ucs_encode(int32_t ch, char *buffer)
-{
- return charset_utf8_encode(ch, buffer);
-}
/* Function: mchar_locale_utf8
@@ -161,9 +135,5 @@ sys_unicode_locale(int isterminal)
{
return mchar_locale_utf8(sys_get_locale(isterminal));
}
-/*end*/
-
-
-
-
+/*end*/
diff --git a/gr/playback.c b/gr/playback.c
index 75ea245d..5a55163a 100644
--- a/gr/playback.c
+++ b/gr/playback.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_playback_c,"$Id: playback.c,v 1.32 2019/01/26 22:27:08 cvsuser Exp $")
+__CIDENT_RCSID(gr_playback_c,"$Id: playback.c,v 1.33 2021/10/17 12:12:06 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: playback.c,v 1.32 2019/01/26 22:27:08 cvsuser Exp $
+/* $Id: playback.c,v 1.33 2021/10/17 12:12:06 cvsuser Exp $
*
*
* This file is part of the GRIEF Editor.
@@ -744,7 +744,7 @@ playback_grab(int popit)
void
playback_macro(const char *cp)
{
- BUFFER_t *bp, *saved_bp = curbp;
+ BUFFER_t *bp, *ocurbp = curbp;
if (!x_playback_recording || x_rem_string[0] == 'P') {
return;
@@ -765,8 +765,7 @@ playback_macro(const char *cp)
return;
}
- curbp = bp;
- set_hooked();
+ set_curbp(bp);
BFSET(curbp, BF_NO_UNDO);
if ('s' == *cp && 0 == strcmp(cp, "self_insert")) {
@@ -838,7 +837,6 @@ playback_macro(const char *cp)
}
rem_doing_self_insert = FALSE;
}
- curbp = saved_bp;
- set_hooked();
+ set_curbp(ocurbp);
}
/*end*/
diff --git a/gr/position.c b/gr/position.c
index 7eefe6a3..1346fefd 100644
--- a/gr/position.c
+++ b/gr/position.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_position_c,"$Id: position.c,v 1.6 2014/10/22 02:33:14 ayoung Exp $")
+__CIDENT_RCSID(gr_position_c,"$Id: position.c,v 1.8 2021/10/17 12:10:13 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: position.c,v 1.6 2014/10/22 02:33:14 ayoung Exp $
+/* $Id: position.c,v 1.8 2021/10/17 12:10:13 cvsuser Exp $
* Buffer position/status.
*
*
@@ -128,8 +128,7 @@ position_restore(int what)
move_abs(pos->p_cur_line, pos->p_cur_col);
if (1 == what) { /* position restore, but not buffer */
- curbp = saved_bp;
- set_hooked();
+ set_curbp(saved_bp);
} else {
attach_buffer(curwp, curbp);
}
@@ -170,7 +169,7 @@ position_dump(void)
trace_log("\t[%2d] %d%d %d/%d ", idx, pos->p_winnum, pos->p_bufnum, pos->p_cur_line, pos->p_cur_col);
if (bp) {
- trace_log(" active \"%s ...\"\n", bp->b_title ? bp->b_title : "n.s.");
+ trace_log(" active \"%s ...\"\n", bp->b_title ? c_string(bp->b_title) : "n.s.");
} else {
trace_log(" closed \"%s ...\"\n", pos->p_name);
}
diff --git a/gr/prntf.c b/gr/prntf.c
index 4daef3ee..8a57160d 100644
--- a/gr/prntf.c
+++ b/gr/prntf.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_prntf_c,"$Id: prntf.c,v 1.13 2017/01/19 17:09:30 cvsuser Exp $")
+__CIDENT_RCSID(gr_prntf_c,"$Id: prntf.c,v 1.16 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: prntf.c,v 1.13 2017/01/19 17:09:30 cvsuser Exp $
+/* $Id: prntf.c,v 1.16 2021/07/05 15:01:27 cvsuser Exp $
* Print formatter.
*
*
@@ -20,6 +20,8 @@ __CIDENT_RCSID(gr_prntf_c,"$Id: prntf.c,v 1.13 2017/01/19 17:09:30 cvsuser Exp $
#include
#include
+#include "../libchartable/libchartable.h"
+#include "../libwidechar/widechar.h"
#include /* str_...()/sxprintf() */
#include "prntf.h"
@@ -57,6 +59,7 @@ typedef struct {
int width;
int precision;
+ int wadjust; /* wchar adjust */
char * obp;
#define ORESET(_x) (_x)->obp = buf_ptr
@@ -71,7 +74,9 @@ typedef struct {
static int get_value(const char **fmt, int *arg);
static void prtl(io_t *io, const LIST *lp, unsigned level);
-static void outs(io_t *io, const char *s);
+static void outs(io_t *io, const char *s, int slen);
+static void wouts(io_t *io, const char *s, int slen);
+static void Wouts(io_t *io, const char *s, int slen);
static void outb(io_t *io, accuint_t ul, const char *p);
static void outl(io_t *io, int radix, accint_t lval);
static void outf(io_t *io, const char *format, accfloat_t dval);
@@ -94,22 +99,26 @@ static int buf_size;
*
* Parameters:
* offset - Format offset within the argument list.
- *
- * len - Address of buffer populated with resulting length.
+ * length - Address of buffer populated with resulting length.
+ * width - Character width.
*
* Returns:
* Address of internal formatted text buffer, reused on each call.
*
*/
const char *
-print_formatted(int offset, int *len)
+print_formatted(int offset, int *length, int *width)
{
+ static const char xBSTR[] = "";
+ static const char xNULL[] = "";
+
const char *fmt;
int arg = offset + 2;
- io_t io, *iop = &io;
+ io_t io = {0}, *iop = &io;
accint_t lval;
const char *sval;
char type;
+ int slen;
if (NULL == buf_ptr) { /* prime buffer */
buf_size = PRINTF_SIZE;
@@ -223,11 +232,13 @@ literal:; OCHECK(iop, 1);
switch (type) {
case 's': /* string */
- sval = ""; /* undefined */
-
+ slen = 0;
if (isa_string(arg)) {
- if (NULL == (sval = get_str(arg))) {
- sval = "";
+ if (NULL != (sval = get_str(arg))) {
+ slen = get_strlen(arg);
+ } else {
+ sval = xNULL;
+ slen = sizeof(xNULL)-1;
}
} else if (isa_list(arg)) { /* 04/04/10 */
prtl(iop, get_list(arg), 0);
@@ -239,9 +250,53 @@ literal:; OCHECK(iop, 1);
outl(iop, 10, (accint_t)get_accfloat(arg));
sval = NULL;
} else if (isa_null(arg)) { /* 04/04/10 */
- sval = "";
+ sval = xNULL;
+ slen = sizeof(xNULL)-1;
+ } else {
+ sval = xBSTR;
+ slen = sizeof(xBSTR)-1;
}
- if (sval) outs(iop, sval);
+ if (sval) outs(iop, sval, slen);
+ ++arg;
+ break;
+
+ case 'S': /* wide/utf8 - characters */
+ slen = 0;
+ if (isa_string(arg)) {
+ if (NULL != (sval = get_str(arg))) {
+ slen = get_strlen(arg);
+ } else {
+ sval = xNULL;
+ slen = sizeof(xNULL)-1;
+ }
+ } else if (isa_null(arg)) {
+ sval = xNULL;
+ slen = sizeof(xNULL)-1;
+ } else {
+ sval = xBSTR;
+ slen = sizeof(xBSTR)-1;
+ }
+ if (sval) wouts(iop, sval, slen);
+ ++arg;
+ break;
+
+ case 'W': /* wide/utf8 - display width */
+ slen = 0;
+ if (isa_string(arg)) {
+ if (NULL != (sval = get_str(arg))) {
+ slen = get_strlen(arg);
+ } else {
+ sval = xNULL;
+ slen = sizeof(xNULL)-1;
+ }
+ } else if (isa_null(arg)) {
+ sval = xNULL;
+ slen = sizeof(xNULL)-1;
+ } else {
+ sval = xBSTR;
+ slen = sizeof(xBSTR)-1;
+ }
+ if (sval) Wouts(iop, sval, slen);
++arg;
break;
@@ -296,7 +351,7 @@ literal:; OCHECK(iop, 1);
*/
lval = get_xaccint(arg++, 0);
if (NULL == (sval = get_xstr(arg++))) {
- sval = "";
+ sval = xBSTR;
}
outb(iop, (accuint_t) lval, sval);
break;
@@ -352,8 +407,11 @@ literal:; OCHECK(iop, 1);
}
}
-end_format:;
- if (len) *len = OLENGTH(iop);
+end_format:;
+ { const int olength = OLENGTH(iop);
+ if (length) *length = olength;
+ if (width) *width = olength - iop->wadjust;
+ }
OPUTC(iop, '\0');
return buf_ptr;
}
@@ -480,16 +538,14 @@ prtl(io_t *io, const LIST *lp, unsigned level)
}
+/* string output */
static void
-outs(io_t *io, const char *s)
+outs(io_t *io, const char *s, int slen)
{
- int slen;
-
/*
- * The precision specifies the maximum number of characters to be
- * printed. Characters in excess of precision are not printed.
+ * Precision specifies the maximum number of characters to be printed.
+ * Characters in excess of precision are not printed.
*/
- slen = strlen(s); /* retrieve string length */
if (io->precision > 0) {
if (io->precision < slen) {
slen = io->precision; /* trim */
@@ -499,6 +555,102 @@ outs(io_t *io, const char *s)
}
+/* long/wide string output - length limited */
+static void
+wouts(io_t *io, const char *s, int slen)
+{
+ const char *cursor = s, *end = cursor + slen;
+ int precision = (io->precision > 0 ? io->precision : INT_MAX);
+ int padding = 0, length = 0, buflen = 0;
+
+ /*
+ * Precision specifies the maximum number of characters to be printed.
+ * Characters in excess of precision are not printed.
+ *
+ * Width defines the upper display width, padding if required.
+ */
+ while (cursor < end && precision > 0) {
+ const char *cend; /* MCHAR */
+ int32_t wch;
+
+ if ((cend = charset_utf8_decode_safe(cursor, end, &wch)) > cursor) {
+ --precision;
+ buflen += (cend - cursor);
+ cursor = cend;
+ ++length;
+ continue;
+ }
+ break; //done
+ }
+
+ if (io->width > length) {
+ padding = io->width - length;
+ }
+
+ OCHECK(io, padding + buflen);
+ if ((io->flags & F_LEFTJUST) == 0)
+ while (padding-- > 0) {
+ OPUTC(io, ' ');
+ }
+ io->wadjust = buflen - length; /* wchar/char delta */
+ OPUTS(io, s, buflen);
+ if (io->flags & F_LEFTJUST)
+ while (padding-- > 0) {
+ OPUTC(io, ' ');
+ }
+}
+
+
+/* long/wide string output - display width limited */
+static void
+Wouts(io_t *io, const char *s, int slen)
+{
+ const char *cursor = s, *end = cursor + slen;
+ int precision = (io->precision > 0 ? io->precision : INT_MAX);
+ int padding = 0, width = 0, buflen = 0;
+
+ /*
+ * Precision specifies the maximum number of characters to be printed.
+ * Characters in excess of precision are not printed.
+ *
+ * Width defines the upper display width, padding if required.
+ */
+ while (cursor < end && precision > 0) {
+ const char *cend; /* MCHAR */
+ int32_t wch;
+ int wc;
+
+ if ((cend = charset_utf8_decode_safe(cursor, end, &wch)) > cursor &&
+ (wc = Wcwidth(wch)) >= 0) {
+ if (wc <= precision) {
+ precision -= wc;
+ buflen += (cend - cursor);
+ cursor = cend;
+ width += wc;
+ continue;
+ }
+ }
+ break; //done
+ }
+
+ if (io->width > width) {
+ padding = io->width - width;
+ }
+
+ OCHECK(io, padding + buflen);
+ if ((io->flags & F_LEFTJUST) == 0)
+ while (padding-- > 0) {
+ OPUTC(io, ' ');
+ }
+ io->wadjust = buflen - width; /* wchar/char delta */
+ OPUTS(io, s, buflen);
+ if (io->flags & F_LEFTJUST)
+ while (padding-- > 0) {
+ OPUTC(io, ' ');
+ }
+}
+
+
static void
outb(io_t *io, accuint_t ul, const char *p)
{
@@ -722,8 +874,9 @@ outf(io_t *io, const char *format, accfloat_t fval)
}
+/* string write */
static void
-outr(io_t *io, const char *s, int len)
+outr(io_t *io, const char *s, int length)
{
int padding = 0;
@@ -740,17 +893,18 @@ outr(io_t *io, const char *s, int len)
* is not given, all characters of the value are printed (subject to the precision
* specification).
*/
+ assert(length >= 0);
if (io->width > 0) {
- padding = io->width - len; /* width specifies output columns */
+ padding = io->width - length; /* width specifies output columns */
+ assert(padding >= 0);
}
- OCHECK(io, padding + len);
+ OCHECK(io, padding + length);
if ((io->flags & F_LEFTJUST) == 0)
while (padding-- > 0) {
OPUTC(io, ' ');
}
-
- OPUTS(io, s, len);
+ OPUTS(io, s, length);
if (io->flags & F_LEFTJUST)
while (padding-- > 0) {
OPUTC(io, ' ');
@@ -773,4 +927,5 @@ uitoa(accuint_t value, char *buffer, int base)
*s = '\0'; /* NUL terminate the string */
str_rev(buffer);
}
-/*end*/
\ No newline at end of file
+
+/*end*/
diff --git a/gr/prntf.h b/gr/prntf.h
index 1b07eee1..0d23d3d4 100644
--- a/gr/prntf.h
+++ b/gr/prntf.h
@@ -1,11 +1,11 @@
#ifndef GR_PRNTF_H_INCLUDED
#define GR_PRNTF_H_INCLUDED
#include
-__CIDENT_RCSID(gr_prntf_h,"$Id: prntf.h,v 1.5 2014/10/22 02:33:14 ayoung Exp $")
+__CIDENT_RCSID(gr_prntf_h,"$Id: prntf.h,v 1.6 2021/07/05 15:01:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: prntf.h,v 1.5 2014/10/22 02:33:14 ayoung Exp $
+/* $Id: prntf.h,v 1.6 2021/07/05 15:01:27 cvsuser Exp $
* Print formatter.
*
*
@@ -25,7 +25,7 @@ __CPRAGMA_ONCE
__CBEGIN_DECLS
-extern const char * print_formatted(int offset, int *len);
+extern const char * print_formatted(int offset, int *len, int *width);
__CEND_DECLS
diff --git a/gr/pty_win32.c b/gr/pty_win32.c
index d7d7d086..a1d1e2c3 100644
--- a/gr/pty_win32.c
+++ b/gr/pty_win32.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_pty_win32_c,"$Id: pty_win32.c,v 1.21 2018/11/18 00:20:21 cvsuser Exp $")
+__CIDENT_RCSID(gr_pty_win32_c,"$Id: pty_win32.c,v 1.22 2022/03/21 15:39:39 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: pty_win32.c,v 1.21 2018/11/18 00:20:21 cvsuser Exp $
+/* $Id: pty_win32.c,v 1.22 2022/03/21 15:39:39 cvsuser Exp $
*
*
* This file is part of the GRIEF Editor.
@@ -154,7 +154,7 @@ dpcreate(DISPLAY_t *dp, const char *shell, const char *cwd)
//
assert(sizeof(HANDLE) == sizeof(dp->d_handle_in));
in = _open_osfhandle((long) hInputWrite, _O_NOINHERIT);
- if ((pid = w32_spawn(&args, in, -1, &out)) <= 0) {
+ if ((pid = w32_spawnA(&args, in, -1, &out)) <= 0) {
CloseHandle((HANDLE) hInputRead);
fileio_close(in);
diff --git a/gr/regdfa.c b/gr/regdfa.c
index 15dca387..288e912b 100644
--- a/gr/regdfa.c
+++ b/gr/regdfa.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_regdfa_c,"$Id: regdfa.c,v 1.32 2020/04/21 00:01:57 cvsuser Exp $")
+__CIDENT_RCSID(gr_regdfa_c,"$Id: regdfa.c,v 1.33 2021/06/18 14:41:57 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: regdfa.c,v 1.32 2020/04/21 00:01:57 cvsuser Exp $
+/* $Id: regdfa.c,v 1.33 2021/06/18 14:41:57 cvsuser Exp $
* DFA regular expression engine.
* Streamlined engine for use by the syntax hiliting code.
*
@@ -2004,4 +2004,5 @@ regdfa_pmatch(struct regdfa *regex, const char *str, int sol, const char **start
}
return -1;
}
+
/*end*/
diff --git a/gr/region.c b/gr/region.c
index 3ce1ba33..b6f4d0ec 100644
--- a/gr/region.c
+++ b/gr/region.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_region_c,"$Id: region.c,v 1.28 2014/10/22 02:33:16 ayoung Exp $")
+__CIDENT_RCSID(gr_region_c,"$Id: region.c,v 1.30 2021/10/17 12:09:43 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: region.c,v 1.28 2014/10/22 02:33:16 ayoung Exp $
+/* $Id: region.c,v 1.30 2021/10/17 12:09:43 cvsuser Exp $
* Region primitives.
*
*
@@ -299,14 +299,14 @@ region_process(const REGION_t *r, region_process_t *rdata)
static int
textstart(const LINE_t *lp, int line, int col)
{
- return line_offset2((LINE_t *)lp, line, (col > 1 ? col : 1), LOFFSET_FIRSTBYTE);
+ return line_offset_const(lp, line, (col > 1 ? col : 1), LOFFSET_FIRSTBYTE);
}
static int
textend(const LINE_t *lp, int line, int col)
{
- return line_offset2((LINE_t *)lp, line, (col > 1 ? col : 1), LOFFSET_LASTBYTE);
+ return line_offset_const(lp, line, (col > 1 ? col : 1), LOFFSET_LASTBYTE);
}
@@ -474,8 +474,7 @@ do_transfer(void) /* int (int bufnum, int sline, int scolumn, int
REGION_t r;
saved_scrap = k_set(curbp); /* destination */
- curbp = bp; /* source */
- set_hooked();
+ set_curbp(bp); /* source */
if (isa_undef(4) && isa_undef(5)) { /* line mode */
a.type = MK_LINE;
@@ -506,8 +505,7 @@ do_transfer(void) /* int (int bufnum, int sline, int scolumn, int
}
k_set(saved_scrap); /* restore default scrap */
- curbp = saved_bp;
- set_hooked();
+ set_curbp(saved_bp);
}
acc_assign_int(ret);
diff --git a/gr/search.c b/gr/search.c
index 15a7230e..c9666152 100644
--- a/gr/search.c
+++ b/gr/search.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_search_c,"$Id: search.c,v 1.55 2021/04/05 08:22:53 cvsuser Exp $")
+__CIDENT_RCSID(gr_search_c,"$Id: search.c,v 1.57 2021/10/17 12:09:17 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: search.c,v 1.55 2021/04/05 08:22:53 cvsuser Exp $
+/* $Id: search.c,v 1.57 2021/10/17 12:09:17 cvsuser Exp $
* Search interface.
*
* TODO:
@@ -917,8 +917,7 @@ do_re_search(void) /* int ([int flags], [string pattern], [declare
if (bp != curbp) {
saved_bp = curbp;
- curbp = bp;
- set_hooked();
+ set_curbp(bp);
}
if (SF_CAPTURES & flags) { /* captures, globalise state */
@@ -946,8 +945,7 @@ do_re_search(void) /* int ([int flags], [string pattern], [declare
}
if (saved_bp) {
- curbp = saved_bp;
- set_hooked();
+ set_curbp(saved_bp);
}
}
acc_assign_int(result);
@@ -1359,13 +1357,11 @@ do_re_translate(void) /* ([int flags], string pattern, [string replace
if (bp != curbp) {
saved_bp = curbp;
- curbp = bp;
- set_hooked();
+ set_curbp(bp);
}
translate_buf(dir, global, flags, -2, 3);
if (saved_bp) {
- curbp = saved_bp;
- set_hooked();
+ set_curbp(saved_bp);
}
}
@@ -2525,7 +2521,7 @@ buffer_search(struct re_state *rs, int cursor)
const LINE_t *clp;
- clp = vm_lock_line(search_line);
+ clp = vm_lock_line2(search_line);
if (clp) {
if (offset > 0) {
if (ltext(clp)) { /* clip to length */
@@ -2945,10 +2941,8 @@ replace_buffer(struct re_state *rs, int interactive)
rs->search_offset = edot + (0 == rs->search_result);
} else if (--rs->search_offset < 0) {
- LINE_t *lp;
-
if (--rs->search_line) {
- lp = vm_lock_line(rs->search_line);
+ const LINE_t *lp = vm_lock_line(rs->search_line);
rs->search_offset = llength(lp);
vm_unlock(rs->search_offset);
}
diff --git a/gr/sh_win32.c b/gr/sh_win32.c
index c119078d..b72accda 100644
--- a/gr/sh_win32.c
+++ b/gr/sh_win32.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_sh_win32_c,"$Id: sh_win32.c,v 1.25 2020/04/13 01:24:51 cvsuser Exp $")
+__CIDENT_RCSID(gr_sh_win32_c,"$Id: sh_win32.c,v 1.26 2022/03/21 15:39:39 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: sh_win32.c,v 1.25 2020/04/13 01:24:51 cvsuser Exp $
+/* $Id: sh_win32.c,v 1.26 2022/03/21 15:39:39 cvsuser Exp $
*
*
* This file is part of the GRIEF Editor.
@@ -169,7 +169,7 @@ sys_shell(const char *cmd, const char *macro,
argv[3] = NULL;
args.argv = argv; // create the process
- if ((hProc = w32_child_exec(&args, pd.hInput, pd.hOutput, pd.hError)) == 0) {
+ if ((hProc = w32_child_execA(&args, pd.hInput, pd.hOutput, pd.hError)) == 0) {
ShellCleanup((void *)&pd);
status = -1;
diff --git a/gr/spell_hunspell.c b/gr/spell_hunspell.c
index 7f86a8f4..c49d2cf2 100644
--- a/gr/spell_hunspell.c
+++ b/gr/spell_hunspell.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_spell_hunspell_c,"$Id: spell_hunspell.c,v 1.17 2014/10/26 22:13:13 ayoung Exp $")
+__CIDENT_RCSID(gr_spell_hunspell_c,"$Id: spell_hunspell.c,v 1.18 2021/06/10 06:13:02 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: spell_hunspell.c,v 1.17 2014/10/26 22:13:13 ayoung Exp $
+/* $Id: spell_hunspell.c,v 1.18 2021/06/10 06:13:02 cvsuser Exp $
* Spell implementation - hunspell driver.
*
* http://sourceforge.net/hunspell/projects
@@ -513,7 +513,7 @@ hs_dict_resolve(const char **paths, const char *name, int len, const char *ext)
}
if (NULL != (expanded = file_expand(buf, expand, sizeof(expand)))) {
trace_log("=> resolve [%s -> %s]\n", buf, expanded);
- if (0 == access(expanded, R_OK)) {
+ if (0 == sys_access(expanded, R_OK)) {
return chk_salloc(expanded);
}
}
diff --git a/gr/syntax.c b/gr/syntax.c
index bc5e062c..cf64cdfe 100644
--- a/gr/syntax.c
+++ b/gr/syntax.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_syntax_c,"$Id: syntax.c,v 1.58 2020/04/13 01:22:57 cvsuser Exp $")
+__CIDENT_RCSID(gr_syntax_c,"$Id: syntax.c,v 1.59 2021/06/10 06:13:02 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: syntax.c,v 1.58 2020/04/13 01:22:57 cvsuser Exp $
+/* $Id: syntax.c,v 1.59 2021/06/10 06:13:02 cvsuser Exp $
* Syntax pre-processor.
*
*
@@ -2297,8 +2297,8 @@ parse_lines(SyntaxTable_t *st, LINENO lineno, LINENO num)
ED_TRACE(("syntax::parse_lines(flags:0x%04x, lineno:%d, num:%d, numline:%d)\n", \
st->st_flags, lineno, num, (int)curbp->b_numlines))
- lp = vm_lock_line(lineno);
- while (1) { /* parse current line */
+ lp = vm_lock_line2(lineno);
+ while (lp) { /* parse current line */
lineflags_t state = parse_line(st, lp);
liflagclr(lp, LI_DIRTY);
diff --git a/gr/sys_unix.c b/gr/sys_unix.c
index 997bb132..c789621d 100644
--- a/gr/sys_unix.c
+++ b/gr/sys_unix.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_sys_unix_c,"$Id: sys_unix.c,v 1.61 2020/06/03 16:31:33 cvsuser Exp $")
+__CIDENT_RCSID(gr_sys_unix_c,"$Id: sys_unix.c,v 1.63 2021/06/02 15:28:38 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: sys_unix.c,v 1.61 2020/06/03 16:31:33 cvsuser Exp $
+/* $Id: sys_unix.c,v 1.63 2021/06/02 15:28:38 cvsuser Exp $
* System dependent functionality - UNIX.
*
*
@@ -788,10 +788,30 @@ sys_copy(const char *src, const char *dst, int perms, int owner, int group)
}
-/* Function: sys_realpath
- * Retrieve the real/absolute for the specified path.
- *
+/* Function: sys_xxx
+ * System i/o primitives.
*/
+int
+sys_mkdir(const char *path, int amode)
+{
+ return mkdir(path, amode);
+}
+
+
+int
+sys_access(const char *path, int amode)
+{
+ return access(path, amode);
+}
+
+
+int
+sys_chmod(const char *path, int mode)
+{
+ return chmod(path, mode);
+}
+
+
int
sys_realpath(const char *name, char *buf, int size)
{
@@ -817,6 +837,41 @@ sys_realpath(const char *name, char *buf, int size)
}
+int
+sys_stat(const char *path, struct stat *sb)
+{
+ return stat(path, sb);
+}
+
+
+int
+sys_lstat(const char *path, struct stat *sb)
+{
+ return lstat(path, sb);
+}
+
+
+int
+sys_readlink(const char *path, char *buf, int maxlen)
+{
+ return readlink(path, buf, maxlen);
+}
+
+
+int
+sys_symlink(const char *name1, const char *name2)
+{
+ return symlink(name1, name2);
+}
+
+
+int
+sys_unlink(const char *fname)
+{
+ return unlink(fname);
+}
+
+
/*
* sys_time ---
* High resolution time, seconds plus milliseconds.
diff --git a/gr/sys_win32.c b/gr/sys_win32.c
index 7c51ec15..51c242f4 100644
--- a/gr/sys_win32.c
+++ b/gr/sys_win32.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_sys_win32_c,"$Id: sys_win32.c,v 1.59 2020/05/03 21:41:40 cvsuser Exp $")
+__CIDENT_RCSID(gr_sys_win32_c,"$Id: sys_win32.c,v 1.63 2021/07/12 15:55:01 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: sys_win32.c,v 1.59 2020/05/03 21:41:40 cvsuser Exp $
+/* $Id: sys_win32.c,v 1.63 2021/07/12 15:55:01 cvsuser Exp $
* WIN32 system support.
*
*
@@ -351,11 +351,14 @@ ResizeCheck(unsigned *checks)
static int
Modifiers(const DWORD dwControlKeyState)
{
+#define CTRLSTATUSMASK (LEFT_ALT_PRESSED|LEFT_CTRL_PRESSED|RIGHT_ALT_PRESSED|RIGHT_CTRL_PRESSED|SHIFT_PRESSED)
+#define ALT_PRESSED (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)
+#define CTRL_PRESSED (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED)
int modifiers = 0;
- if (dwControlKeyState & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED))
+ if (dwControlKeyState & ALT_PRESSED)
modifiers |= MOD_META;
- if (dwControlKeyState & (LEFT_CTRL_PRESSED|RIGHT_CTRL_PRESSED))
+ if (dwControlKeyState & CTRL_PRESSED)
modifiers |= MOD_CTRL;
if (dwControlKeyState & SHIFT_PRESSED)
modifiers |= MOD_SHIFT;
@@ -388,6 +391,122 @@ MouseEvent(const DWORD dwEventFlags, const DWORD dwButtonState)
}
+// Alt+ event handler
+//
+// Alt+KeyCode works and behaves well when character only input is required, by simply
+// reporting any down or up key events which populate the 'UnicodeChar' value. Whereas
+// when extended keystroke handling is required, for example arrow and numpad keys,
+// additional effort is needed.
+//
+// Alt+Keycodes are only reported within the 'UnicodeChar' value of up event on a "ALT" key
+// post the valid entry of one-or-more hex characters. During KeyCode entry the API unfortunately
+// does not publiciy indicate this state plus continues to return the associated virtual keys,
+// including the leading 'keypad-plus' and any associated key-code elements, wherefore we need
+// to filter. Furthermore, if during the key-code entry an invalid non-hex key combination is
+// given, the key-code is invalidated and UnicodeChar=0 is returned on the ALT release.
+//
+// Notes:
+// o To enable requires the registry REG_SZ value "EnableHexNumpad" under
+// "HKEY_Current_User/Control Panel/Input Method" to be "1".
+//
+// o Hex-value overflow goes unreported, limiting input to a 16-bit unicode result.
+//
+
+#pragma comment(lib, "Imm32.lib")
+
+static int
+AltPlusEnabled(void)
+{
+ HKEY hKey = 0;
+ int enabled = 0;
+
+ if (RegOpenKeyExA(HKEY_CURRENT_USER,
+ "Control Panel\\Input Method", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
+ char szEnableHexNumpad[100] = {0};
+ DWORD dwSize = _countof(szEnableHexNumpad);
+ if (RegQueryValueExA(hKey, "EnableHexNumpad", NULL, NULL, (LPBYTE) szEnableHexNumpad, &dwSize) == ERROR_SUCCESS) {
+ if (szEnableHexNumpad[0] == '1' && szEnableHexNumpad[1] == 0) {
+ enabled = 1;
+ }
+ }
+ RegCloseKey(hKey);
+ }
+ return enabled;
+}
+
+static int
+AltPlusEvent(const KEY_EVENT_RECORD *ke, struct IOEvent *evt)
+{
+#define ISXDIGIT(_uc) \
+ ((_uc >= '0' && _uc <= '9') || (_uc >= 'a' && _uc <= 'f') || (_uc >= 'A' && _uc <= 'F') ? 1 : 0)
+
+ static int alt_code = -2; // >0=active, 0=enabled, -1=disabled, -2=auto.
+ static DWORD alt_control = 0;
+
+ if (alt_code < 0) {
+ if (-1 == alt_code) return -1;
+ if (! AltPlusEnabled()) {
+ alt_code = -1;
+ return -1;
+ }
+ alt_code = 0;
+ }
+
+ if (ke->bKeyDown) { // down event
+ const unsigned controlKeyState = (CTRLSTATUSMASK & ke->dwControlKeyState);
+
+ if (VK_ADD == ke->wVirtualKeyCode &&
+ (LEFT_ALT_PRESSED == controlKeyState || RIGHT_ALT_PRESSED == controlKeyState)) {
+ // "Alt + ..." event
+ alt_control = controlKeyState;
+ if (alt_code == 0) {
+ alt_code = 1;
+ }
+ return 1; // consume
+
+ } else if (alt_code) {
+ if (alt_control != controlKeyState ||
+ (ke->uChar.UnicodeChar && 0 == ISXDIGIT(ke->uChar.UnicodeChar))) {
+ // new control status or non-hex, emit "Alt-Plus" and reset state
+ evt->type = EVT_KEYDOWN;
+ evt->code = KEYPAD_PLUS;
+ evt->modifiers = MOD_ALT;
+ alt_code = 0;
+ return 0;
+ }
+
+ ++alt_code; // associated key count
+ return 1; // consume
+ }
+
+ } else if (alt_code) { // up event
+ if (VK_MENU == ke->wVirtualKeyCode &&
+ (0 == (ke->dwControlKeyState & ALT_PRESSED))) {
+ // Alt completion
+ const int oalt_code = alt_code;
+
+ alt_code = 0;
+ if (1 == oalt_code && 0 == ke->uChar.UnicodeChar) {
+ // "Alt-Plus" only, emit
+ evt->type = EVT_KEYDOWN;
+ evt->code = KEYPAD_PLUS;
+ evt->modifiers = MOD_ALT;
+ return 0;
+
+ } else if (ke->uChar.UnicodeChar) {
+ // "Alt-Plus keycode", return keycode.
+ evt->type = EVT_KEYDOWN;
+ evt->code = ke->uChar.UnicodeChar;
+ evt->modifiers = 0;
+ return 0;
+ }
+ }
+ }
+
+ return -1; // unhandled
+}
+
+
/* Function: sys_getevent
* Retrieve the input event from the status keyboard stream, within
* the specified timeout 'tmo'.
@@ -423,24 +542,34 @@ sys_getevent(struct IOEvent *evt, int tmo)
ticks = DiffTicks(ticks); /* ticks (ms) as end */
if (rc == WAIT_OBJECT_0 &&
- ReadConsoleInput(hKbd, &k, 1, &count)) {
+ ReadConsoleInputW(hKbd, &k, 1, &count)) {
switch (k.EventType) {
- case KEY_EVENT:
- if (k.Event.KeyEvent.bKeyDown) {
+ case KEY_EVENT: {
const KEY_EVENT_RECORD *ke = &k.Event.KeyEvent;
- int code;
+
+ { /* Alt+KeyCode (experimental) */
+ const int altstate = AltPlusEvent(ke, evt);
+ if (altstate == 0) return 0;
+ if (altstate == 1) break;
+ }
+
+ if (k.Event.KeyEvent.bKeyDown) {
+ int code;
/* see kbd.c */
- if ((code = key_mapwin32((unsigned) ke->dwControlKeyState,
- ke->wVirtualKeyCode, ke->uChar.AsciiChar)) != -1) {
- evt->type = EVT_KEYDOWN;
- evt->code = code;
- evt->modifiers = Modifiers(ke->dwControlKeyState);
- assert(code > 0 && code < KEY_VOID);
- return 0;
+ if ((code = key_mapwin32((unsigned) ke->dwControlKeyState,
+ ke->wVirtualKeyCode, ke->uChar.UnicodeChar)) != -1) {
+
+ evt->type = EVT_KEYDOWN;
+ evt->code = code;
+ evt->modifiers = Modifiers(ke->dwControlKeyState);
+ assert(code > 0 && code <= (MOD_MASK|RANGE_MASK|KEY_MASK) && code != KEY_VOID);
+ return 0;
+ }
+
+ } else {
+ resize = ResizeCheck(&checks);
}
- } else {
- resize = ResizeCheck(&checks);
}
break;
@@ -842,7 +971,7 @@ sys_copy(
__CUNUSED(owner)
#endif
if ((rc = CopyFileA(src, dst, FALSE)) != FALSE) {
- (void) fileio_chmod(dst, perms); /* FIXME: return */
+ (void) sys_chmod(dst, perms); /* FIXME: return */
#ifdef HAVE_CHOWN
chown(dst, owner, group);
#endif
@@ -852,14 +981,34 @@ sys_copy(
}
-/* Function: sys_realpath
- * Retrieve the real/absolute for the speified path.
- *
+/* Function: sys_xxx
+ * System i/o primitives.
*/
+int
+sys_mkdir(const char *path, int amode)
+{
+ return w32_mkdir(path, amode);
+}
+
+
+int
+sys_access(const char *path, int amode)
+{
+ return w32_access(path, amode);
+}
+
+
+int
+sys_chmod(const char *path, int mode)
+{
+ return w32_chmod(path, (mode_t)mode);
+}
+
+
int
sys_realpath(const char *name, char *buf, int size)
{
- return (NULL == _fullpath(buf, name, size) ? -1 : 0);
+ return (NULL == w32_realpath2(name, buf, size) ? -1 : 0);
}
diff --git a/gr/sysinfo.c b/gr/sysinfo.c
index 1a0936d9..094ab077 100644
--- a/gr/sysinfo.c
+++ b/gr/sysinfo.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_sysinfo_c,"$Id: sysinfo.c,v 1.49 2021/04/19 16:28:49 cvsuser Exp $")
+__CIDENT_RCSID(gr_sysinfo_c,"$Id: sysinfo.c,v 1.51 2021/06/02 15:29:09 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: sysinfo.c,v 1.49 2021/04/19 16:28:49 cvsuser Exp $
+/* $Id: sysinfo.c,v 1.51 2021/06/02 15:29:09 cvsuser Exp $
* System information services.
*
*
@@ -161,7 +161,7 @@ sysinfo_homedir(char *buf, int len)
t_path[0] = 0; /* XP+ */
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, t_path)) && *t_path) {
t_path[sizeof(t_path) - 1] = 0;
- if (0 == fileio_access(t_path, 0)) {
+ if (0 == sys_access(t_path, 0)) {
p = t_path;
} else {
char buffer[MAX_PATH*2];
@@ -255,7 +255,7 @@ sysinfo_tmpdir(void)
t_path[0] = 0; /* XP+ */
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, t_path)) && *t_path) {
t_path[sizeof(t_path) - 1] = 0;
- if (0 == fileio_access(t_path, 0)) {
+ if (0 == sys_access(t_path, 0)) {
p = t_path;
}
} else {
@@ -265,7 +265,7 @@ sysinfo_tmpdir(void)
--pathlen; /* remove trailing delimiter */
}
t_path[pathlen] = 0;
- if (0 == fileio_access(t_path, 0)) {
+ if (0 == sys_access(t_path, 0)) {
p = t_path;
}
}
@@ -322,7 +322,7 @@ sysinfo_tmpdir(void)
}
}
#endif
- if (0 == fileio_access(xtmpdir, W_OK)) {
+ if (0 == sys_access(xtmpdir, W_OK)) {
p = tmpdirs[d];
break;
}
@@ -343,7 +343,7 @@ tmpdir2(const char *env)
const char *p;
if ((p = ggetenv(env)) != NULL && p[0] &&
- 0 == fileio_access(p, 0)) {
+ 0 == sys_access(p, 0)) {
return p;
}
return NULL;
@@ -467,13 +467,13 @@ resolve_execname(const char *name)
#endif
if (sys_isabspath(name)) { /* absolute path */
- if (-1 != stat(name, &sb) && !S_ISDIR(sb.st_mode)) {
+ if (-1 != sys_stat(name, &sb) && !S_ISDIR(sb.st_mode)) {
trace_log("execname: [abs], <%s>\n", name);
goto done;
}
/* relative, resolve and test */
} else if (0 == sys_realpath((const char *)name, t_path, sizeof(t_path)) && t_path[0]) {
- if (-1 != stat(t_path, &sb) && !S_ISDIR(sb.st_mode)) {
+ if (-1 != sys_stat(t_path, &sb) && !S_ISDIR(sb.st_mode)) {
trace_log("execname: [rel], <%s>\n", t_path);
name = t_path;
goto done;
@@ -498,7 +498,7 @@ resolve_execname(const char *name)
}
trace_log("execname: [path], <%s>\n", t_path);
- if (stat(t_path, &sb) >= 0 && !S_ISDIR(sb.st_mode)) {
+ if (sys_stat(t_path, &sb) >= 0 && !S_ISDIR(sb.st_mode)) {
name = t_path;
goto done;
}
diff --git a/gr/system.h b/gr/system.h
index 676c2eea..7546f4cb 100644
--- a/gr/system.h
+++ b/gr/system.h
@@ -1,11 +1,11 @@
#ifndef GR_SYSTEM_H_INCLUDED
#define GR_SYSTEM_H_INCLUDED
#include
-__CIDENT_RCSID(gr_system_h,"$Id: system.h,v 1.37 2020/06/18 12:46:40 cvsuser Exp $")
+__CIDENT_RCSID(gr_system_h,"$Id: system.h,v 1.38 2021/06/02 15:29:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: system.h,v 1.37 2020/06/18 12:46:40 cvsuser Exp $
+/* $Id: system.h,v 1.38 2021/06/02 15:29:27 cvsuser Exp $
* System interface.
*
*
@@ -55,6 +55,9 @@ extern int sys_isabspath(const char *path);
extern const char * sys_pathdelimiter(void);
extern const char * sys_pathseparator(void);
+extern int sys_mkdir(const char *path, int amode);
+extern int sys_access(const char *path, int amode);
+extern int sys_chmod(const char *path, int mode);
extern int sys_realpath(const char *path, char *real, int size);
extern const char * sys_cwd(char *cwd, int size);
extern int sys_read(int fd, void *buf, int size);
diff --git a/gr/termemu_vio.c b/gr/termemu_vio.c
index 97104cc0..a6cb1c4f 100644
--- a/gr/termemu_vio.c
+++ b/gr/termemu_vio.c
@@ -2,7 +2,7 @@
/*
* libtermemu console driver
*
- * Copyright (c) 2007, 2012 - 2020 Adam Young.
+ * Copyright (c) 2007, 2012 - 2022 Adam Young.
*
* This file is part of the GRIEF Editor.
*
@@ -18,7 +18,7 @@
/*
* Notes:
- * o Extended 256 color mode is experimental/work in progress.
+ * o 256 color mode available under both Legacy and Win10 enhanced console.
* o Use of non-monospaced fonts are not advised unless UNICODE characters are required.
* o Neither wide nor combined characters are fully addressed.
*/
@@ -28,8 +28,14 @@
#endif
#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
+#define _WIN32_WINNT 0x601
+#else
+#if(_WIN32_WINNT < 0x601)
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x601
+#endif
#endif
+
#define PSAPI_VERSION 1 // EnumProcessModules and psapi.dll
#if !defined(WINDOWS_MEAN_AND_LEAN)
#define WINDOWS_MEAN_AND_LEAN
@@ -51,6 +57,10 @@
#define WIN32_CONSOLEEXT /* extended console */
#define WIN32_CONSOLE256 /* enable 256 color console support */
+#if defined(__WATCOMC__)
+#pragma disable_message(124) /* Comparison result always 0 / 1 */
+#endif
+
#pragma comment(lib, "Gdi32.lib")
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "Kernel32.lib")
@@ -524,6 +534,8 @@ vio_trace(const char *fmt, ...)
if (debug[len-1] != '\n') debug[len] = '\n', debug[len+1] = 0;
OutputDebugStringA(debug);
va_end(ap);
+#else //_DEBUG
+ (void)fmt;
#endif //_DEBUG
}
@@ -569,7 +581,9 @@ vio_init(void)
} else if (rows > VIO_MAXROWS) {
rows = VIO_MAXROWS; // limit to supported width.
}
+
if (cols < VIO_MINCOLS) cols = VIO_MINCOLS;
+ //Note: shouldnt occur, console limits ~6 to accommodate def buttons.
if (fontprofile || vio.cols != cols || vio.rows != rows) {
const WCHAR_INFO *oimage;
@@ -593,7 +607,7 @@ vio_init(void)
assert(vio.chandle);
assert(vio.whandle);
- vio.size = rows * cols;
+ vio.size = rows * cols; // buffer size, in elements
oimage = vio.image;
vio.image = (WCHAR_INFO *)calloc(vio.size, sizeof(WCHAR_INFO));
if (oimage) { // screen has resized
@@ -628,6 +642,7 @@ vio_init(void)
vio.c_trashed = 1;
vio.rows = rows;
vio.cols = cols;
+
vio_goto(vio.c_row, vio.c_col); // limit current cursor
for (l = 0; l < rows; ++l) {
@@ -859,7 +874,7 @@ vio_profile(int rebuild)
vio.fcfamily = cfix.FontFamily;
vio.fcweight = cfix.FontWeight;
vio.fcfamily = -1;
- wcstombs(vio.fcfacename, cfix.FaceName, sizeof(vio.fcfacename));
+ wcstombs(vio.fcfacename, cfix.FaceName, sizeof(vio.fcfacename) /*bytes*/);
}
} else {
@@ -948,7 +963,7 @@ vio_profile(int rebuild)
TRACE_LOG(("Console Facenames (%u)\n", (unsigned)count))
TRACE_LOG((" Idx W x H Fam Wgt Facename\n"))
for (f = 0; f < count; ++f, ++cursor) {
- wcstombs(t_facename, cursor->FaceName, sizeof(t_facename));
+ wcstombs(t_facename, cursor->FaceName, sizeof(t_facename) /*bytes*/);
TRACE_LOG((" %2d: %2u x %2u, %4u, %4u, <%s>\n", (int)cursor->nFont, \
(unsigned)cursor->dwFontSize.X, (unsigned)cursor->dwFontSize.Y, \
(unsigned)cursor->FontFamily, (unsigned)cursor->FontWeight, t_facename))
@@ -1031,7 +1046,8 @@ IsVirtualConsole(int *depth)
#endif
#if !defined(ENABLE_INSERT_MODE)
#define ENABLE_INSERT_MODE 0x0020
- // When enabled, text entered in a console window will be inserted at the current cursor location and all text following that location will not be overwritten.
+ // When enabled, text entered in a console window will be inserted at the current cursor location and
+ // all text following that location will not be overwritten.
// When disabled, all following text will be overwritten.
// To enable this mode, use ENABLE_INSERT_MODE | ENABLE_EXTENDED_FLAGS.
// To disable this mode, use ENABLE_EXTENDED_FLAGS without this flag.
@@ -1043,7 +1059,7 @@ IsVirtualConsole(int *depth)
// To disable this mode, use ENABLE_EXTENDED_FLAGS without this flag.
#endif
#if !defined(ENABLE_EXTENDED_FLAGS)
-#define ENABLE_EXTENDED_FLAGS 0x0080
+#define ENABLE_EXTENDED_FLAGS 0x0080
// Required to enable or disable extended flags. See ENABLE_INSERT_MODE and ENABLE_QUICK_EDIT_MODE.
#endif
@@ -1066,7 +1082,7 @@ IsVirtualConsole(int *depth)
*depth = t_depth;
return TRUE;
} else if (SetConsoleMode(chandle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
- (void)SetConsoleMode(chandle, mode);
+ (void) SetConsoleMode(chandle, mode);
*depth = t_depth;
return TRUE;
}
@@ -1478,7 +1494,7 @@ CopyOut(copyoutctx_t *ctx, unsigned pos, unsigned cnt, unsigned flags)
if (-1 == ctx->cursormode) { // hide cursor, if visible
GetConsoleCursorInfo(chandle, &ctx->cursorinfo);
if (0 != (ctx->cursormode = ctx->cursorinfo.bVisible)) {
- ctx->cursorinfo.bVisible = FALSE;
+ ctx->cursorinfo.bVisible = FALSE;
(void) SetConsoleCursorInfo(chandle, &ctx->cursorinfo);
}
}
@@ -1730,7 +1746,7 @@ CopyOutEx(copyoutctx_t *ctx, size_t pos, size_t cnt, unsigned flags)
const WCHAR_INFO cell = *cursor++;
if (start >= 0) { // attribute run
- if (SameAttributesFGBG(&cell, &info, fg, bg, VIO_BOLD|VIO_BLINK|VIO_ITALIC|VIO_FAINT)) {
+ if (SameAttributesFGBG(&cell, &info, fg, bg, VIO_BOLD|VIO_BLINK|VIO_ITALIC|VIO_FAINT|VIO_INVERSE)) {
ocursor[col++] = cell; // update out image
*text = (WCHAR)cell.Char.UnicodeChar;
if (++text >= etext)
@@ -1753,14 +1769,17 @@ CopyOutEx(copyoutctx_t *ctx, size_t pos, size_t cnt, unsigned flags)
text = textbuf;
info = cell.Info;
COLOR256(&info, &fg, &bg);
+ if (info.Attributes & VIO_INVERSE) {
+ SWAPRGB(fg, bg);
+ }
if (start > 0) { // if previous is space, also redraw; address font cell draw bleeding.
const WCHAR_INFO backcell = cursor[-2];
if ((IsSpace(cell.Char.UnicodeChar) &&
- SameAttributesFGBG(&backcell, &info, fg, bg, VIO_BOLD | VIO_BLINK | VIO_ITALIC | VIO_FAINT)) ||
+ SameAttributesFGBG(&backcell, &info, fg, bg, VIO_BOLD|VIO_BLINK|VIO_ITALIC|VIO_FAINT|VIO_INVERSE)) ||
(IsSpace(backcell.Char.UnicodeChar) &&
- SameAttributesBG(&backcell, &info, bg, VIO_BOLD | VIO_BLINK | VIO_ITALIC | VIO_FAINT))) {
+ SameAttributesBG(&backcell, &info, bg, VIO_BOLD|VIO_BLINK|VIO_ITALIC|VIO_FAINT|VIO_INVERSE))) {
*text++ = (WCHAR)backcell.Char.UnicodeChar;
--start;
}
@@ -1922,11 +1941,16 @@ CopyOutEx2(copyoutctx_t *ctx, size_t pos, size_t cnt, unsigned flags)
do {
const WCHAR_INFO cell = *cursor++;
+ if (0 == cell.Char.UnicodeChar) {
+ ++col;
+ continue; // NULL, padding
+ }
+
// ESC[; H CUP, Cursor Position *Cursor moves to ; coordinate within the viewport, where is the column of the line.
//
if (-1 == start) {
if (0 == (flags & TRASHED) &&
- SameCell(&cell, ocursor + col)) {
+ SameCell(&cell, ocursor + col)) {
++col;
continue; // up-to-date
}
@@ -2268,6 +2292,7 @@ consolefontsenum(void)
// Typefaces for Source Code Beautification.
//
// Fonts:
+ // https://github.com/powerline/fonts
// http://www.proggyfonts.net/
// http://www.levien.com/type/myfonts/inconsolata.html
// http://terminus-font.sourceforge.net/ and https://files.ax86.net/terminus-ttf/
@@ -2543,19 +2568,26 @@ WCHAR_BUILD(const uint32_t ch, const struct WCHAR_COLORINFO *info, WCHAR_INFO *c
}
+static BOOL
+WATTR_COMPARE(const WCHAR_INFO *c1, const struct WCHAR_COLORINFO *info2)
+{
+ if (c1->Info.Flags || info2->Flags) {
+ return (c1->Info.Flags == info2->Flags &&
+ c1->Info.Attributes == info2->Attributes &&
+ c1->Info.fg == info2->fg &&
+ c1->Info.bg == info2->bg &&
+ c1->Info.fgrgb == info2->fgrgb &&
+ c1->Info.bgrgb == info2->bgrgb);
+ }
+ return (c1->Info.Attributes == info2->Attributes);
+}
+
+
static BOOL
WCHAR_COMPARE(const WCHAR_INFO *c1, const WCHAR_INFO *c2)
{
if (c1->Char.UnicodeChar == c2->Char.UnicodeChar) {
- if (c1->Info.Flags || c2->Info.Flags) {
- return (c1->Info.Flags == c2->Info.Flags &&
- c1->Info.Attributes == c2->Info.Attributes &&
- c1->Info.fg == c2->Info.fg &&
- c1->Info.bg == c2->Info.bg &&
- c1->Info.fgrgb == c2->Info.fgrgb &&
- c1->Info.bgrgb == c2->Info.bgrgb);
- }
- return (c1->Info.Attributes == c2->Info.Attributes);
+ return WATTR_COMPARE(c1, &c2->Info);
}
return FALSE;
}
@@ -2764,15 +2796,16 @@ vio_save(void)
rows = 1 + sbinfo.srWindow.Bottom - sbinfo.srWindow.Top;
cols = 1 + sbinfo.srWindow.Right - sbinfo.srWindow.Left;
- if (!vio_state.image || vio_state.rows != rows || vio_state.cols != cols) {
- CHAR_INFO *newImage;
+ if (!vio_state.image || // initial or size change
+ vio_state.rows != rows || vio_state.cols != cols) {
+ CHAR_INFO *nimage;
if (rows <= 0 || cols <= 0 ||
- NULL == (newImage = calloc(rows * cols, sizeof(CHAR_INFO)))) {
+ NULL == (nimage = calloc(rows * cols, sizeof(CHAR_INFO)))) {
return;
}
free(vio_state.image); // release previous; if any
- vio_state.image = newImage;
+ vio_state.image = nimage;
vio_state.rows = rows;
vio_state.cols = cols;
}
@@ -2805,8 +2838,8 @@ ImageSave(HANDLE console, unsigned pos, unsigned cnt)
wr.Top = (SHORT)(pos / cols);
wr.Bottom = (SHORT)((pos + (cnt - 1)) / cols);
- is.Y = (SHORT)(vio.rows - wr.Top); // size of image.
- is.X = (SHORT)(vio.cols);
+ is.Y = (SHORT)(rows - wr.Top); // size of image.
+ is.X = (SHORT)(cols);
ic.X = 0; // top left src cell in image.
ic.Y = 0;
@@ -3164,6 +3197,7 @@ vio_goto(int row, int col)
{
if (row >= vio.rows) row = vio.rows-1;
vio.c_row = row;
+
if (col >= vio.cols) col = vio.cols-1;
vio.c_col = col;
}
@@ -3221,6 +3255,8 @@ vio_define_attr(int obj, const char *what, const char *fg, const char *bg)
// }
if (VIO_INVERSE & (fattr|battr)) { // apply inverse.
+ fattr &= ~VIO_INVERSE;
+ battr &= ~VIO_INVERSE;
SWAPFGBG(fcolor, bcolor);
SWAPRGB(frgb, brgb);
}
@@ -3282,7 +3318,11 @@ vio_define_winattr(int obj, int fg, int bg, uint16_t attributes)
assert(bg >= WIN_COLOR_MIN && bg < WIN_COLOR_NUM);
if (obj < 0 || obj >= MAXOBJECTS) return;
- if (VIO_INVERSE & attributes) SWAPFGBG(fg, bg);
+ if (VIO_INVERSE & attributes) {
+ attributes &= ~VIO_INVERSE;
+ SWAPFGBG(fg, bg);
+ }
+
if (fg < 0 || bg < 0) { // specials, dynamic
vio.c_attrs[obj].Flags = VIO_F16; // vt/xterm
vio.c_attrs[obj].Attributes = attributes;
@@ -3314,8 +3354,13 @@ vio_define_vtattr(int obj, int fg, int bg, uint16_t attributes)
vio.c_attrs[obj].Flags = VIO_F256;
if (vio.maxcolors > 16) vio.activecolors = 256;
}
+
+ if (VIO_INVERSE & attributes) {
+ attributes &= ~VIO_INVERSE;
+ SWAPFGBG(fg, bg);
+ }
+
vio.c_attrs[obj].Attributes = attributes;
- if (VIO_INVERSE & attributes) SWAPFGBG(fg, bg);
vio.c_attrs[obj].fg = (short)vtnormal(fg);
vio.c_attrs[obj].bg = (short)vtnormal(bg);
vio.c_attrs[obj].fgrgb = (COLORREF)-1;
@@ -3333,8 +3378,13 @@ vio_define_rgbattr(int obj, int fg, int bg, uint16_t attributes)
vio.c_attrs[obj].Flags = VIO_FRGB; // true-color
if (vio.maxcolors > 16) vio.activecolors = 256;
+
+ if (VIO_INVERSE & attributes) {
+ attributes &= ~VIO_INVERSE;
+ SWAPFGBG(fg, bg);
+ }
+
vio.c_attrs[obj].Attributes = attributes;
- if (VIO_INVERSE & attributes) SWAPFGBG(fg, bg);
vio.c_attrs[obj].fg = (short)rgb_search(16, fg); // shadow colors (vt/xterm)
vio.c_attrs[obj].bg = (short)rgb_search(16, bg);
vio.c_attrs[obj].fgrgb = (COLORREF)fg; // true-colors
@@ -3394,7 +3444,11 @@ vio_set_wincolor(int fg, int bg, uint16_t attributes)
assert(fg >= WIN_COLOR_MIN && fg < WIN_COLOR_NUM);
assert(bg >= WIN_COLOR_MIN && bg < WIN_COLOR_NUM);
- if (VIO_INVERSE & attributes) SWAPFGBG(fg, bg);
+ if (VIO_INVERSE & attributes) {
+ attributes &= ~VIO_INVERSE;
+ SWAPFGBG(fg, bg);
+ }
+
if (fg < 0 || bg < 0) { // specials, dynamic
vio.c_color.Flags = VIO_F16; // vt/xterm
vio.c_color.Attributes = attributes;
@@ -3425,8 +3479,12 @@ vio_set_vtcolor(int fg, int bg, uint16_t attributes)
vio.c_color.Flags = VIO_F16;
if (fg >= 16 || bg >= 16) vio.c_color.Flags = VIO_F256;
+ if (VIO_INVERSE & attributes) {
+ attributes &= ~VIO_INVERSE;
+ SWAPFGBG(fg, bg);
+ }
+
vio.c_color.Attributes = attributes;
- if (VIO_INVERSE & attributes) SWAPFGBG(fg, bg);
vio.c_color.fg = (short)vtnormal(fg); // primary colors (vt/xterm)
vio.c_color.bg = (short)vtnormal(bg);
vio.c_color.fgrgb = (COLORREF)-1; // true-colors (none)
@@ -3446,8 +3504,12 @@ vio_set_rgbcolor(int32_t fg, int32_t bg, uint16_t attributes)
vio.c_color.Flags = VIO_FRGB;
if (vio.maxcolors > 16) vio.activecolors = 256;
+ if (VIO_INVERSE & attributes) {
+ attributes &= VIO_INVERSE;
+ SWAPFGBG(fg, bg);
+ }
+
vio.c_color.Attributes = attributes;
- if (VIO_INVERSE & attributes) SWAPFGBG(fg, bg);
vio.c_color.fg = (short)rgb_search(16, fg); // shadow colors (vt/xterm)
vio.c_color.bg = (short)rgb_search(16, bg);
vio.c_color.fgrgb = (COLORREF)fg; // true-colors
diff --git a/gr/termemu_vio.h b/gr/termemu_vio.h
index eaf74fa5..fc86f421 100644
--- a/gr/termemu_vio.h
+++ b/gr/termemu_vio.h
@@ -1,14 +1,14 @@
#ifndef TERMEMU_VIO_H_INCLUDED
#define TERMEMU_VIO_H_INCLUDED
#include
-__CIDENT_RCSID(termemu_vio_h,"$Id: termemu_vio.h,v 1.3 2020/05/04 20:20:18 cvsuser Exp $")
+__CIDENT_RCSID(termemu_vio_h,"$Id: termemu_vio.h,v 1.4 2021/06/10 06:13:02 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
/*
* libtermemu console driver
*
- * Copyright (c) 2007, 2012 - 2018 Adam Young.
+ * Copyright (c) 2007, 2012 - 2020 Adam Young.
*
* This file is part of the GRIEF Editor.
*
diff --git a/gr/tty.c b/gr/tty.c
index cad3f051..961782a1 100644
--- a/gr/tty.c
+++ b/gr/tty.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_tty_c,"$Id: tty.c,v 1.29 2014/10/22 02:33:22 ayoung Exp $")
+__CIDENT_RCSID(gr_tty_c,"$Id: tty.c,v 1.30 2021/06/22 15:52:54 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: tty.c,v 1.29 2014/10/22 02:33:22 ayoung Exp $
+/* $Id: tty.c,v 1.30 2021/06/22 15:52:54 cvsuser Exp $
* Common basic tty functionality.
*
*
@@ -92,9 +92,6 @@ ttdefaults(void)
x_pt.pt_lineno_columns = -1; /* Line-number display columns. */
x_pt.pt_window_minrows = -1; /* Window rows limit. */
x_pt.pt_window_mincols = -1; /* Window column limit. */
-
- x_pt.pt_unicode_version = 500; /* Unicode 5.00 */
- x_pt.pt_unicode_width = 500; /* 300 or 500 */
}
diff --git a/gr/ttyterm.c b/gr/ttyterm.c
index 2cc851cb..3dff4c27 100644
--- a/gr/ttyterm.c
+++ b/gr/ttyterm.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_ttyterm_c,"$Id: ttyterm.c,v 1.110 2021/04/05 08:04:31 cvsuser Exp $")
+__CIDENT_RCSID(gr_ttyterm_c,"$Id: ttyterm.c,v 1.115 2021/10/15 10:32:48 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: ttyterm.c,v 1.110 2021/04/05 08:04:31 cvsuser Exp $
+/* $Id: ttyterm.c,v 1.115 2021/10/15 10:32:48 cvsuser Exp $
* TTY driver termcap/terminfo based.
*
*
@@ -32,6 +32,7 @@ __CIDENT_RCSID(gr_ttyterm_c,"$Id: ttyterm.c,v 1.110 2021/04/05 08:04:31 cvsuser
#include
#include /* gputenvv(), ggetenv() */
+
#if defined(_VMS)
#include
#include
@@ -179,16 +180,30 @@ typedef struct {
const char * termcapname; /* termcap name */
const char * terminfoname; /* terminfo name */
const char * comment; /* comment string */
- void * token; /* optional user token */
#define TC_DESC(__desc) __desc
-#define TC_TOKEN(__token) (void *)(__token)
-
- union {
- const char *i_str;
- int i_val;
- } value; /* value */
} Term_t;
+typedef struct {
+ Term_t term;
+ int key;
+#define TC_TOKEN(__token) __token
+ const char * svalue; /* runtime value */
+} TermKey_t;
+
+typedef struct {
+ Term_t term;
+ const char ** stoken;
+#define TC_STRING(__token) __token
+ const char * svalue; /* runtime value */
+} TermString_t;
+
+typedef struct {
+ Term_t term;
+ int * itoken;
+#define TC_FLAG(__token) __token
+ int ivalue; /* runtime value*/
+} TermNumeric_t;
+
static void term_open(scrprofile_t *profile);
static void term_ready(int repaint, scrprofile_t *profile);
static void term_feature(int ident, scrprofile_t *profile);
@@ -521,11 +536,11 @@ static GraphicChars_t term_characters[] = { /* graphic characters */
{ TACS_VLINE, TC_DESC("vertical line") }
};
-static Term_t term_strings[] = { /* strings - termcap/terminfo elements */
- { "ac", "acsc", TC_DESC("acs characters"), &tc_graphic_pairs },
+static TermString_t term_strings[] = { /* strings - termcap/terminfo elements */
+ { "ac", "acsc", TC_DESC("acs characters"), TC_STRING(&tc_graphic_pairs) },
{ "bt", "cbt", TC_DESC("back tab")},
- { "bl", "bel", TC_DESC("audible signal (bell)"), &tc_bl },
- { "cr", "cr", TC_DESC("carriage return"), &tc_cr },
+ { "bl", "bel", TC_DESC("audible signal (bell)"), TC_STRING(&tc_bl) },
+ { "cr", "cr", TC_DESC("carriage return"), TC_STRING(&tc_cr) },
{ "ZA", "cpi", TC_DESC("change number of characters per inch") },
{ "ZB", "lpi", TC_DESC("change number of lines per inch") },
{ "ZC", "chr", TC_DESC("change horizontal resolution") },
@@ -675,9 +690,9 @@ static Term_t term_strings[] = { /* strings - termcap/terminfo el
{ "PU", "pulse", TC_DESC("select pulse dialling") },
{ "QD", "qdial", TC_DESC("dial number #1 without checking") },
{ "RC", "rmclk", TC_DESC("remove clock") },
- { "rp", "rep", TC_DESC("repeat char #1 #2 times"), &tc_rp},
+ { "rp", "rep", TC_DESC("repeat char #1 #2 times"), &tc_rp },
{ "RF", "rfi", TC_DESC("send next input char (for ptys)") },
- { "rs", NULL, TC_DESC("terminal reset string"), &tc_rs},
+ { "rs", NULL, TC_DESC("terminal reset string"), &tc_rs },
{ "r1", "rs1", TC_DESC("reset string") },
{ "r2", "rs2", TC_DESC("reset string") },
{ "r3", "rs3", TC_DESC("reset string") },
@@ -802,8 +817,8 @@ static Term_t term_strings[] = { /* strings - termcap/terminfo el
/*
* Others
*/
- { "cS", NULL, TC_DESC("change region to line #1 to line #2, alt form"), &tc_cS},
- { "bc", NULL, TC_DESC("move left, if not ^H (old-style)"), &tc_bc},
+ { "cS", NULL, TC_DESC("change region to line #1 to line #2, alt form"), &tc_cS },
+ { "bc", NULL, TC_DESC("move left, if not ^H (old-style)"), &tc_bc },
{ "nl", NULL, TC_DESC("use to move down") },
/* { "ko", NULL, TC_DESC("list of self-mapped keycaps") }, */
/* { "ma", NULL, TC_DESC("map arrow keys rogue(1) motion keys") }, */
@@ -858,7 +873,7 @@ static const struct {
#endif /*XXX_KO*/
-static Term_t term_numbers[] = { /* numeric - termcap/terminfo elements */
+static TermNumeric_t term_numbers[] = { /* numeric - termcap/terminfo elements */
/*
* standard
*/
@@ -900,7 +915,7 @@ static Term_t term_numbers[] = { /* numeric - termcap/terminfo el
};
-static Term_t term_keys[] = { /* keys - termcap/terminfo elements */
+static TermKey_t term_keys[] = { /* keys - termcap/terminfo elements */
{ "!1", "kSAV", TC_DESC("shifted save key") },
{ "!2", "kSPD", TC_DESC("shifted suspend key") },
{ "!3", "kUND", TC_DESC("shifted undo key"), TC_TOKEN(KEY_REDO) },
@@ -1052,14 +1067,14 @@ static Term_t term_keys[] = { /* keys - termcap/terminfo elemen
{ "ku", "kcuu1", TC_DESC("up-arrow key"), TC_TOKEN(KEY_UP) },
};
-static Term_t term_flags[] = { /* boolean - termcap/terminfo elements */
+static TermNumeric_t term_flags[] = { /* boolean - termcap/terminfo elements */
{ "5i", "mc5i", TC_DESC("printer won't echo on screen") },
{ "HC", "chts", TC_DESC("cursor is hard to see") },
- { "LP", NULL, TC_DESC("last column of last line will not scroll"), TC_TOKEN(&tf_LP) },
+ { "LP", NULL, TC_DESC("last column of last line will not scroll"), TC_FLAG(&tf_LP) },
{ "MT", NULL, TC_DESC("has meta key") }, /* TODO */
{ "ND", "ndscr", TC_DESC("scrolling region is non-destructive") },
- { "NL", NULL, TC_DESC("move down with \\n"), TC_TOKEN(&tf_NL) },
- { "NP", "npc", TC_DESC("pad character does not exist"), TC_TOKEN(&tf_npc) },
+ { "NL", NULL, TC_DESC("move down with \\n"), TC_FLAG(&tf_NL) },
+ { "NP", "npc", TC_DESC("pad character does not exist"), TC_FLAG(&tf_npc) },
{ "NR", "nrrmc", TC_DESC("smcup does not reverse rmcup") },
{ "YA", "xhpa", TC_DESC("only positive motion for hpa/mhpa caps") },
{ "YB", "crxm", TC_DESC("using cr turns off micro mode") },
@@ -1068,37 +1083,37 @@ static Term_t term_flags[] = { /* boolean - termcap/terminfo el
{ "YE", "sam", TC_DESC("printing in last column causes cr") },
{ "YF", "cpix", TC_DESC("changing character pitch changes resolution") },
{ "YG", "lpix", TC_DESC("changing line pitch changes resolution") },
- { "am", "am", TC_DESC("terminal has automatic margins"), TC_TOKEN(&tf_am) },
- { "be", NULL, TC_DESC("back color erase"), TC_TOKEN(&tf_be) },
- { "bs", NULL, TC_DESC("uses ^H to move left"), TC_TOKEN(&tf_bs) },
+ { "am", "am", TC_DESC("terminal has automatic margins"), TC_FLAG(&tf_am) },
+ { "be", NULL, TC_DESC("back color erase"), TC_FLAG(&tf_be) },
+ { "bs", NULL, TC_DESC("uses ^H to move left"), TC_FLAG(&tf_bs) },
{ "bw", "bw", TC_DESC("cub1 wraps from column 0 to last column") },
{ "cc", "ccc", TC_DESC("terminal can re-define existing colors") },
{ "da", "da", TC_DESC("display may be retained above the screen") },
{ "db", "db", TC_DESC("display may be retained below the screen") },
{ "eo", "eo", TC_DESC("can erase overstrikes with a blank") },
{ "es", "eslok", TC_DESC("escape can be used on the status line") },
- { "gn", "gn", TC_DESC("generic line type"), TC_TOKEN(&tf_gn) },
- { "hc", "hc", TC_DESC("hardcopy terminal"), TC_TOKEN(&tf_hc) },
+ { "gn", "gn", TC_DESC("generic line type"), TC_FLAG(&tf_gn) },
+ { "hc", "hc", TC_DESC("hardcopy terminal"), TC_FLAG(&tf_hc) },
{ "hl", "hls", TC_DESC("terminal uses only HLS color notation (tektronix)") },
{ "hs", "hs", TC_DESC("has extra status line") },
- { "hz", "hz", TC_DESC("can't print ~'s (hazeltine)"), TC_TOKEN(&tf_hz) },
+ { "hz", "hz", TC_DESC("can't print ~'s (hazeltine)"), TC_FLAG(&tf_hz) },
{ "in", "in", TC_DESC("insert mode distinguishes nulls") },
- { "km", "km", TC_DESC("Has a meta key, sets msb high"), TC_TOKEN(&tf_km) },
+ { "km", "km", TC_DESC("Has a meta key, sets msb high"), TC_FLAG(&tf_km) },
{ "mi", "mir", TC_DESC("safe to move while in insert mode") },
- { "ms", "msgr", TC_DESC("safe to move while in standout/underline mode"), TC_TOKEN(&tf_ms) },
+ { "ms", "msgr", TC_DESC("safe to move while in standout/underline mode"), TC_FLAG(&tf_ms) },
{ "nc", NULL, TC_DESC("no way to go to start of line") },
{ "ns", NULL, TC_DESC("crt cannot scroll") },
- { "nx", "nxon", TC_DESC("padding won't work, xon/xoff required"), TC_TOKEN(&tf_xonoff) },
+ { "nx", "nxon", TC_DESC("padding won't work, xon/xoff required"), TC_FLAG(&tf_xonoff) },
{ "os", "os", TC_DESC("terminal can overstrike") },
{ "pt", NULL, TC_DESC("has 8-char tabs invoked with ^I") },
{ "ul", "ul", TC_DESC("underline character overstrikes") },
- { "ut", "bce", TC_DESC("screen erased with background color"), TC_TOKEN(&tf_ut) },
+ { "ut", "bce", TC_DESC("screen erased with background color"), TC_FLAG(&tf_ut) },
{ "xb", "xsb", TC_DESC("beehive (f1=escape, f2=ctrl C)") },
- { "xn", "xenl", TC_DESC("newline ignored after 80 cols (concept)"), TC_TOKEN(&tf_xn) },
- { "xo", NULL, TC_DESC("terminal uses xon/xoff handshaking"), TC_TOKEN(&tf_xonoff) },
+ { "xn", "xenl", TC_DESC("newline ignored after 80 cols (concept)"), TC_FLAG(&tf_xn) },
+ { "xo", NULL, TC_DESC("terminal uses xon/xoff handshaking"), TC_FLAG(&tf_xonoff) },
{ "xr", "xon", TC_DESC("return clears the line") },
- { "xs", "xhp", TC_DESC("standout not erased by overwriting (hp)"), TC_TOKEN(&tf_xs) },
- { "xt", "xt", TC_DESC("tabs destructive, magic so char (Telray 1061)"), TC_TOKEN(&tf_xt) }
+ { "xs", "xhp", TC_DESC("standout not erased by overwriting (hp)"), TC_FLAG(&tf_xs) },
+ { "xt", "xt", TC_DESC("tabs destructive, magic so char (Telray 1061)"), TC_FLAG(&tf_xt) }
};
@@ -1151,12 +1166,14 @@ static const struct colormap { /* BRIEF -> XTERM color map */
{ COLOR_NONE, -1, -1, -1, -1, -1, -1, -1 }
};
+
/*
* Scroll window
*/
static int tt_top = -1; /* Top of scroll region. */
static int tt_bot = -1; /* Bottom of scroll region. */
+
/*
* Color information
*/
@@ -1326,8 +1343,8 @@ ttinit(void)
} else if (term_xtermlike(term)) { /* eg. xterm-color */
t_attributes = TA_XTERM | TA_XTERMLIKE;
#if defined(__CYGWIN__)
- if (ggetenv("COMSPEC")) {
- t_attributes |= TA_DARK; /* assume cmd/mintty */
+ if (ggetenv("COMSPEC")) {
+ t_attributes |= TA_DARK; /* assume cmd/mintty */
}
#endif /*__CYGWIN__*/
}
@@ -1363,17 +1380,18 @@ ttinit(void)
/*
* string values
*/
- const Term_t *ti = term_strings + i;
- const char *name = ttiname(ti);
+ TermString_t *ti = term_strings + i;
+ const Term_t *term = &ti->term;
+ const char *name = ttiname(term);
- if (name && NULL != (cp = ttigetstr(ti))) {
- const char **token = term_strings[i].token;
+ if (name && NULL != (cp = ttigetstr(term))) {
+ const char **token = ti->stoken;
- term_strings[i].value.i_str = cp;
+ ti->svalue = cp;
if (token) {
- *token = cp;
+ *token = ti->svalue;
}
- trace_log("\t%-50s%c %-5s : %s\n", term_strings[i].comment,
+ trace_log("\t%-50s%c %-5s : %s\n", term->comment,
(token ? '*' : ' '), name, c_string(cp));
if (token == &tc_graphic_pairs) {
@@ -1399,15 +1417,16 @@ ttinit(void)
/*
* keys
*/
- const Term_t *ti = term_keys + i;
- const char *name = ttiname(ti);
+ TermKey_t *ti = term_keys + i;
+ const Term_t *term = &ti->term;
+ const char *name = ttiname(term);
- if (name && NULL != (cp = ttigetstr(ti))) {
- const size_t kcode = (size_t)term_keys[i].token;
+ if (name && NULL != (cp = ttigetstr(term))) {
+ const size_t kcode = (size_t)ti->key;
- term_keys[i].value.i_str = cp; /* loaded later by ttkeys() */
+ ti->svalue = cp; /* loaded later by ttkeys() */
- trace_log("\t%-50s%c %-5s : %s\n", term_keys[i].comment,
+ trace_log("\t%-50s%c %-5s : %s\n", term->comment,
(kcode ? '*' : ' '), name, c_string(cp));
if (kcode >= F(1) && kcode <= F(10)) {
@@ -1425,16 +1444,17 @@ ttinit(void)
/*
* numbers
*/
- const Term_t *ti = term_numbers + i;
- const char *name = ttiname(ti);
+ TermNumeric_t *ti = term_numbers + i;
+ const Term_t *term = &ti->term;
+ const char *name = ttiname(term);
if (name) {
- term_numbers[i].value.i_val = ttigetnum(ti);
- if (term_numbers[i].token) {
- *((int *)term_numbers[i].token) = term_numbers[i].value.i_val;
+ ti->ivalue = ttigetnum(term);
+ if (ti->itoken) {
+ *ti->itoken = ti->ivalue;
}
- trace_log("\t%-50s%c %-5s : %d\n", term_numbers[i].comment,
- (term_numbers[i].token ? '*' : ' '), name, term_numbers[i].value.i_val);
+ trace_log("\t%-50s%c %-5s : %d\n", term->comment,
+ (ti->itoken ? '*' : ' '), name, ti->ivalue);
}
}
@@ -1443,16 +1463,17 @@ ttinit(void)
/*
* flags
*/
- const Term_t *ti = term_flags + i;
- const char *name = ttiname(ti);
+ TermNumeric_t *ti = term_flags + i;
+ const Term_t *term = &ti->term;
+ const char *name = ttiname(term);
if (name) {
- term_flags[i].value.i_val = ttigetflag(ti);
- if (term_flags[i].token) {
- *((int *)term_flags[i].token) = term_flags[i].value.i_val;
+ ti->ivalue = ttigetflag(term);
+ if (ti->itoken) {
+ *ti->itoken = ti->ivalue;
}
- trace_log("\t%-50s%c %-5s : %d\n", term_flags[i].comment,
- (term_flags[i].token ? '*' : ' '), name, term_flags[i].value.i_val);
+ trace_log("\t%-50s%c %-5s : %d\n", term->comment,
+ (ti->itoken ? '*' : ' '), name, ti->ivalue);
}
}
}
@@ -1813,9 +1834,9 @@ term_ready(int repaint, scrprofile_t *profile)
}
} else if (t_attributes & TA_MINTTY) {
-// if (! xf_mouse) {
+ if (xf_mouse) { /* mouse enabled? */
ttpush("\033[?7786h"); /* mouse-wheel reports only */
-// }
+ }
} else if (t_attributes & TA_VT100LIKE) {
ttpush("\033=\033[?1]"); /* enable cursor keys */
@@ -1896,8 +1917,11 @@ term_feature(int ident, scrprofile_t *profile)
break;
case TF_ENCODING:
+ break;
case TF_UNICODE_VERSION:
- case TF_UNICODE_WIDTH:
+ if (x_pt.pt_unicode_version[0]) {
+ ucs_width_set(x_pt.pt_unicode_version);
+ }
break;
}
}
@@ -2404,8 +2428,8 @@ ttkeys(void)
* Keys
*/
for (i = 0; i < (sizeof(term_keys)/sizeof(term_keys[0])); ++i)
- if (term_keys[i].value.i_str && term_keys[i].token) {
- key_define_key_seq((int)term_keys[i].token, term_keys[i].value.i_str);
+ if (term_keys[i].svalue && term_keys[i].key) {
+ key_define_key_seq(term_keys[i].key, term_keys[i].svalue);
}
/*
@@ -3112,9 +3136,9 @@ term_tidy(void)
ttpush("\033[?2000l"); /* disable RAW mode */
}
} else if (t_attributes & TA_MINTTY) {
-//TODO if (! xf_mouse) {
- ttpush("\033[?7786l"); /* disable mouse-wheel reports */
-// }
+ if (xf_mouse) { /* mouse enabled? */
+ ttpush("\033[?7786l"); /* disable mouse-wheel reports */
+ }
}
term_graphic_exit(); /* graphic mode */
@@ -4724,11 +4748,11 @@ term_putc(vbyte_t c)
* width character enabled displays
*/
if (isutf8 && MCHAR_ISUTF8(c)) { /* MCHAR */
- if ((width = mchar_ucs_width(c, -1)) >= 0) {
+ if ((width = ucs_width(c)) >= 0) {
ED_TRACE3(("ttputc_utf8(row:%d, col:%d, char:%d/0x%x, width:%d)\n",\
ttrow, ttcol, c, c, width))
term_graphic_exit();
- t_count += mchar_ucs_encode(c, (char *)(t_buffer + t_count));
+ t_count += charset_utf8_encode(c, (char *)(t_buffer + t_count));
goto complete;
}
width = 1; /* control */
@@ -5213,4 +5237,3 @@ do_copy_screen(void) /* void () */
}
#endif /*!USE_VIO_BUFFER && !DJGPP */
-
diff --git a/gr/ttyterm.c.001 b/gr/ttyterm.c.001
new file mode 100644
index 00000000..8242a42c
--- /dev/null
+++ b/gr/ttyterm.c.001
@@ -0,0 +1,5219 @@
+#include
+__CIDENT_RCSID(gr_ttyterm_c,"$Id: ttyterm.c,v 1.110 2021/04/05 08:04:31 cvsuser Exp $")
+
+/* -*- mode: c; indent-width: 4; -*- */
+/* $Id: ttyterm.c,v 1.110 2021/04/05 08:04:31 cvsuser Exp $
+ * TTY driver termcap/terminfo based.
+ *
+ *
+ * This file is part of the GRIEF Editor.
+ *
+ * The GRIEF Editor is free software: you can redistribute it
+ * and/or modify it under the terms of the GRIEF Editor License.
+ *
+ * The GRIEF Editor is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * License for more details.
+ * ==end==
+ */
+
+// #define ED_LEVEL 2
+
+#include
+
+#if !defined(USE_VIO_BUFFER) && !defined(DJGPP)
+
+#if defined(__CYGWIN__)
+#include /* GetConsoleOutputCP() */
+#include /* uname */
+#endif
+
+#include
+#include /* gputenvv(), ggetenv() */
+
+
+#if defined(_VMS)
+#include
+#include
+#include
+#include
+#include
+#include
+#endif
+
+#if defined(HAVE_LIBNCURSESW)
+#if defined(HAVE_NCURSESW_CURSESW_H)
+#include
+#include
+#include
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#include
+#include
+#include
+#elif defined(HAVE_NCURSESW_H)
+#include
+#if defined(HAVE_TERMCAP_H)
+#include
+#endif
+#if defined(HAVE_TERM_H)
+#include
+#endif
+#else /*!HAVE_NCURSESW_CURSES_H || HAVE_NCURSESW_H*/
+#error "HAVE_LIBNCURSEW defined yet missing headers, check config"
+#endif
+
+#elif defined(HAVE_LIBNCURSES)
+#if defined(HAVE_NCURSES_NCURSES_H)
+#include
+#include
+#include
+#elif defined(HAVE_NCURSES_CURSES_H)
+#include
+#include
+#include
+#elif defined(HAVE_NCURSES_H)
+#include
+#if defined(HAVE_TERMCAP_H)
+#include
+#endif
+#if defined(HAVE_TERM_H)
+#include
+#endif
+#else /*!HAVE_NCURSES_CURSES_H || HAVE_NCURSES_H*/
+#error "HAVE_LIBNCURSE defined yet missing headers, check config"
+#endif
+
+#elif defined(HAVE_LIBCURSES)
+#if defined(HAVE_CURSES_H)
+#include
+#if defined(HAVE_TERMCAP_H)
+#include
+#endif
+#if defined(HAVE_TERM_H)
+#if defined(HAVE_TERMIO_H)
+#include /* solaris (SGTTY definition) */
+#endif
+#include
+#else /* missing prototypes */
+extern char * tgetstr(char *, char **);
+extern char * tgoto(const char * , int a, int b);
+extern char * tparm(const char *, ...);
+#endif
+#else /*!HAVE_CURSES_H*/
+#error "HAVE_LIBCURSES defined yet missing headers, check config"
+#endif
+
+#elif defined(HAVE_LIBTERMCAP)
+#if defined(HAVE_TERMCAP_H)
+#include
+#else /*HAVE_TERMCAP_H*/
+#error "HAVE_LIBTERMCAP defined yet missing headers, check config"
+#endif
+
+#elif defined(HAVE_LIBTERMLIB)
+#include
+#define HAVE_TERMCAP
+
+#else
+#include "edtermcap.h" /* use local implementation -- BAD */
+#endif
+
+#if defined(HAVE_TERMINFO) && defined(HAVE_TERMCAP)
+#define XF_TERMCAP if (xf_termcap) /* dynamic selection */
+#define XF_TERMINFO if (! xf_termcap)
+#else
+#if !defined(HAVE_TERMINFO) && !defined(HAVE_TERMCAP)
+#error "no terminal interface style defined (TERMINFO nor TERMCAP), check cofig"
+#endif
+#define XF_TERMCAP
+#define XF_TERMINFO
+#endif
+
+#if !defined(HAVE_OSPEED) && !defined(__CYGWIN__) && !defined(sun) && \
+ defined(OSPEED_EXTERN) /* ospeed available? (diag only) */
+#define HAVE_OSPEED
+extern int ospeed;
+#endif
+
+#if defined(HAVE_OUTFUNTYPE) /* tputs() interface */
+#define TPUTS_OUTFUNC (outfuntype)
+#define TPUTS_OUTTYPE int
+#elif defined(TPUTS_TAKES_CHAR)
+#define TPUTS_OUTFUNC (int (*)(char))
+#define TPUTS_OUTTYPE char
+#else
+#define TPUTS_OUTFUNC (int (*)(int))
+#define TPUTS_OUTTYPE int
+#endif
+
+#include /* needs to be after [n]curses.h */
+#include /* str_...()/sxprintf() */
+
+#include "accum.h" /* acc_ ... */
+#include "asciidefs.h"
+#include "cmap.h" /* cmap ... */
+#include "color.h" /* color ... */
+#include "debug.h" /* trace ... */
+#include "display.h"
+#include "echo.h"
+#include "eval.h" /* get_str() ... */
+#include "getkey.h" /* io_... */
+#include "keyboard.h"
+#include "line.h"
+#include "main.h"
+#include "map.h"
+#include "mchar.h" /* mchar_...() */
+#include "mouse.h"
+#include "playback.h"
+#include "procspawn.h"
+#include "system.h"
+#include "tty.h"
+#include "undo.h"
+#include "window.h"
+
+#define ANSI_COLORS 16
+#define XTERM_COLORS 16
+#define NOCOLOR 0x7fff
+
+typedef struct {
+ const char * termcapname; /* termcap name */
+ const char * terminfoname; /* terminfo name */
+ const char * comment; /* comment string */
+ void * token; /* optional user token */
+#define TC_DESC(__desc) __desc
+#define TC_TOKEN(__token) (void *)(__token)
+
+ union {
+ const char *i_str;
+ int i_val;
+ } value; /* value */
+} Term_t;
+
+static void term_open(scrprofile_t *profile);
+static void term_ready(int repaint, scrprofile_t *profile);
+static void term_feature(int ident, scrprofile_t *profile);
+static void term_display(void);
+static int term_control(int action, int param, ...);
+static void term_close(void);
+static int hasfeature(const char *term, const char *what);
+
+static const char * ttisetup(void);
+static const char * ttiname(const Term_t *ti);
+static const char * ttigetstr(const Term_t *ti);
+static int ttigetnum(const Term_t *ti);
+static int ttigetflag(const Term_t *ti);
+
+static int term_xtermlike(const char *term);
+
+static void acs_dump(const char *bp);
+static const char * acs_box_characters(const char *bp);
+static int acs_locale_breaks(void);
+
+static void term_tidy(void);
+static void term_move(int row, int col);
+static int term_cursor(int visible, int imode, int virtual_space);
+static int term_names(const char *title, const char *icon);
+static void term_beep(int freq, int duration);
+
+static void term_colors(void);
+static void term_fgbg(void);
+static const char * fgbg_value(const char *src, int *result);
+static unsigned fgbg_import(unsigned edefault, int udefault);
+
+static void xterm_colors(const char *value);
+static int xterm_colors_get(char *buffer, int length);
+static int xterm_colors_set(const char *value);
+
+static int term_isutf8(void);
+static int term_identification(void);
+static int term_read(char *buf, int blen, accint_t tmo);
+
+static __CINLINE void term_graphic_enter(void);
+static __CINLINE void term_graphic_exit(void);
+
+static void term_clear(void);
+static void term_zero(int restore);
+static void term_flush(void);
+static void term_sizeget(int *nrow, int *ncol);
+
+static void term_putc(vbyte_t c);
+static int term_eeol(void);
+static int term_ce(void);
+static int term_lastsafe(void);
+static void term_eeop(int restore);
+static void term_repeat(int cnt, vbyte_t fill, int where);
+static int term_insl(int row, int bot, int nlines, vbyte_t fillcolor);
+static int term_dell(int row, int bot, int nlines, vbyte_t fillcolor);
+static void term_scrollset(int top, int bot);
+static void term_scrollreset(void);
+static void term_attr(vbyte_t color);
+static void term_styleon(unsigned mode);
+static void term_styleoff(void);
+static void term_colorreset(void);
+static int term_cost(const char *s);
+
+static void ttputpad(const char *str);
+static void ttputctl(const char *str, int a);
+static void ttputctl2(const char *str, int a, int b);
+static void ttprintf(const char *str, ...);
+static void ttprintf2(const char *str, ...);
+
+static void ega_switch(int flag);
+
+/*
+ * This is the output buffer. NOBUF is how many bytes we can put in the buffer. We
+ * leave a lot of room for expansion because a single character may cause us to
+ * output multiple characters (e.g. printing top bit or graphics characters).
+ */
+#define NOOVFLOW 100
+#define NOBUF ((8 * 1024) - NOOVFLOW)
+
+static unsigned t_count;
+static unsigned char t_buffer[NOBUF + NOOVFLOW];
+
+/*
+ * Termcap buffer
+ */
+#define TC_SLEN (1024 * 32) /* 32k - tgetent wants >= 16k */
+
+#if defined(HAVE_TERMCAP)
+static char * tcapcursor;
+static char tcapbuffer[TC_SLEN]; /* termcap buffer */
+static char tcapstrings[TC_SLEN]; /* termcap local storage */
+#endif
+
+/*
+ * Terminate attributes
+ */
+#define TA_XTERM 0x0001
+#define TA_VT100LIKE 0x0002
+#define TA_XTERMLIKE 0x0004
+
+#define TA_LINUX 0x0010
+#define TA_CYGWIN 0x0020
+#define TA_KONSOLE 0x0040
+#define TA_SCREEN 0x0080
+#define TA_MINTTY 0x0100
+
+#define TA_DARK 0x1000 /* generally dark background */
+#define TA_LIGHT 0x2000 /* light */
+#define TA_MONO 0x4000 /* mono terminal */
+
+static unsigned t_attributes; /* attributes */
+static int t_charout; /* number of characters output. */
+static unsigned t_insdel; /* do we have both insert & delete line? */
+static int t_padchar = -1; /* pad character (if any) */
+static int t_acs_locale_breaks;
+
+/*
+ * Terminate status
+ */
+static unsigned t_gmode; /* graphics character set active */
+static int t_cost; /* terminal costing accumulator */
+static unsigned t_specials; /* special bits */
+
+/*
+ * Color control
+ */
+static char t_colorsorg[XTERM_COLORS * 32];
+static char t_colorsuser[XTERM_COLORS * 32];
+
+
+/*
+ * Cached termap controls
+ *
+ * References:
+ * ANSI Standard X3.64-1979.
+ * X/Open System Interface Definitions, Issue 4, Version 2.
+ *
+ * http://www.xfree86.org/current/ctlseqs.html
+ *
+ * http://dickey.his.com/xterm/xterm.faq.html
+ *
+ * http://frexx.de/xterm-256-notes
+ *
+ * http://en.wikipedia.org/wiki/ANSI_escape_code
+ */
+static int
+ tf_gn, /* generic terminal. */
+ tf_hc, /* hard-copy terminal. */
+ tf_npc, /* no pad character. */
+ tf_xonoff, /* xon/xoff required. */
+ tf_am, /* has auto-margins. */
+ tf_xn, /* the cursor wraps in a strange way. */
+ tf_hz, /* no hazel line support. */
+ tf_km, /* meta key sets msb */
+ tf_LP, /* last column safe. */
+ tf_NL, /* move down using \n. */
+ tf_bs, /* move left using ^H. */
+ tf_Colors, /* max colors */
+ tf_Pairs, /* max color-pairs */
+ tf_ut, /* screen erased with background color. */
+ tf_be, /* back color erase (xterm). */
+ tf_xs, tf_xt, /* attribute clear mode */
+ tf_ms; /* save to move cursor whilst standout/underlined */
+
+static int
+ tn_sg, /* number of glitches, 0 for invisable, -1 for none */
+ tn_li, tn_co, /* lines/columns */
+ tn_NC; /* attributes which dont mix with colors */
+
+static const char
+ *tc_ti, /* Term init -- start using cursor motion. */
+ *tc_te, /* Term end --- end using cursor motion. */
+ *tc_ke, /* Enter keypad mode. */
+ *tc_ks, /* Exit keypad mode. */
+ *tc_rs, /* Reset sequence. */
+ *tc_am_on, /* Turn on automatic margins. */
+ *tc_bl, /* Bell. */
+
+ *tc_cm, /* Cursor motion. */
+ *tc_ho, /* Home cursor. */
+ *tc_ll, /* Left-end cursor. */
+ *tc_cr, /* Cursor newline. */
+ *tc_up, /* Cursor up on line. */
+ *tc_pUP, /* Cursor up on line - parameterised. */
+ *tc_do, /* Cursor down. */
+ *tc_pDO, /* Cursor down - parameterised. */
+ *tc_le, /* Cursor left (new style). */
+ *tc_bc, /* Cursor left (old style). */
+ *tc_pBC, /* Cursor left - parameterised. */
+ *tc_nd, /* Cursor right. */
+ *tc_pRI, /* Cursor right - parameterised. */
+ *tc_cv, /* Cursor vertical movement. */
+ *tc_ch, /* Cursor horz movement. */
+
+ *tc_vs, /* Enhance the cursor. */
+ *tc_ve, /* Normal cursor. */
+ *tc_vb, /* Visual bell. */
+ *tc_vi, /* Hide cursor. */
+
+ *tc_cs, /* Set scroll region. */
+ *tc_cS, /* Set scroll region, alt form (see Emacs). */
+ *tc_sf, /* Forward index (used with scroll region). */
+ *tc_sr, /* Back index (used with scroll region). */
+ *tc_pSF, /* Forward index */
+ *tc_pSR, /* Back index */
+
+ *tc_al, /* Add line */
+ *tc_dl, /* Delete line */
+ *tc_pAL, /* Parameterized add line. */
+ *tc_pDL, /* Parameterized delete line. */
+
+ *tc_pc, /* Padding character */
+ *tc_dc, /* Delete a character. */
+ *tc_pDC, /* Parameterized character delete. */
+ *tc_ic, /* Insert a single space. */
+ *tc_cb, /* Clear to beginning of line. */
+ *tc_cd, /* Clear to end of display. */
+ *tc_ce, /* Clear to end of line. */
+ *tc_cl, /* Clear screen. */
+ *tc_rp, /* repeat #1 #2 times */
+ *tc_ech, /* erase #1 characters */
+ *tc_im, /* Insert mode. */
+ *tc_ei, /* End insert mode. */
+
+ *tc_oc, *tc_op, /* Reset colors. */
+ *tc_me, /* Turn off all attributes. */
+ *tc_mm, *tc_mo, /* Turn on/off meta mode (8th-bit on). */
+ *tc_so, *tc_se, /* Start/end standout mode. */
+ *tc_us, *tc_ue, /* Turn on/off underline mode. */
+ *tc_mb, /* Turn on blinking. */
+ *tc_md, /* Make bold. */
+ *tc_ZH, *tc_ZR, /* Italic (on/off). */
+ *tc_mr, *tc_ZX, /* Reverse (on/off). */
+ *tc_sa; /* Attribute set. */
+
+static const char
+ *tc_acs_start, /* as */
+ *tc_acs_end, /* ae */
+ *tc_acs_enable; /* enable ACS */
+
+static unsigned char /* ac */
+ tc_acs_map[129];
+
+static const char tc_graphic_default[] =
+ "a:j+k+l+m+q-t+u+v+w+x|n+`+f\\g#~o,<+>.v-^h#0#";
+
+static const char
+ *tc_graphic_pairs,
+ *tc_box_characters;
+
+static const char
+ *tc_ANSI_Color_Fg, *tc_Color_Fg, /* color selection */
+ *tc_ANSI_Color_Bg, *tc_Color_Bg;
+
+typedef struct {
+ char ident; /* internal identifier */
+ const char * name; /* desc */
+} GraphicChars_t;
+
+enum {
+ /*
+ * ACC mappings, includes ncurse's extensions
+ */
+ TACS_STERLING = '}',
+ TACS_DARROW = '.',
+ TACS_LARROW = ',',
+ TACS_RARROW = '+',
+ TACS_UARROW = '-',
+ TACS_BOARD = 'h',
+ TACS_BULLET = '~',
+ TACS_CKBOARD = 'a',
+ TACS_DEGREE = 'f',
+ TACS_DIAMOND = '`',
+ TACS_GEQUAL = 'z',
+ TACS_PI = '{',
+ TACS_HLINE = 'q',
+ TACS_LANTERN = 'i',
+ TACS_PLUS = 'n',
+ TACS_LEQUAL = 'y',
+ TACS_LLCORNER = 'm',
+ TACS_LRCORNER = 'j',
+ TACS_NEQUAL = '|',
+ TACS_PLMINUS = 'g',
+ TACS_S1 = 'o',
+ TACS_S3 = 'p',
+ TACS_S7 = 'r',
+ TACS_S9 = 's',
+ TACS_BLOCK = '0',
+ TACS_TTEE = 'w',
+ TACS_RTEE = 'u',
+ TACS_LTEE = 't',
+ TACS_BTEE = 'v',
+ TACS_ULCORNER = 'l',
+ TACS_URCORNER = 'k',
+ TACS_VLINE = 'x'
+ };
+
+static GraphicChars_t term_characters[] = { /* graphic characters */
+ { TACS_STERLING, TC_DESC("UK pound sign") },
+ { TACS_DARROW, TC_DESC("arrow pointing down") },
+ { TACS_LARROW, TC_DESC("arrow pointing left") },
+ { TACS_RARROW, TC_DESC("arrow pointing right") },
+ { TACS_UARROW, TC_DESC("arrow pointing up") },
+ { TACS_BOARD, TC_DESC("board of squares") },
+ { TACS_BULLET, TC_DESC("bullet") },
+ { TACS_CKBOARD, TC_DESC("checker board (stipple)") },
+ { TACS_DEGREE, TC_DESC("degree symbol") },
+ { TACS_DIAMOND, TC_DESC("diamond") },
+ { TACS_GEQUAL, TC_DESC("greater-than-or-equal-to") },
+ { TACS_PI, TC_DESC("greek pi") },
+ { TACS_HLINE, TC_DESC("horizontal line") },
+ { TACS_LANTERN, TC_DESC("lantern symbol") },
+ { TACS_PLUS, TC_DESC("large plus or crossover") },
+ { TACS_LEQUAL, TC_DESC("less-than-or-equal-to") },
+ { TACS_LLCORNER, TC_DESC("lower left corner") },
+ { TACS_LRCORNER, TC_DESC("lower right corner") },
+ { TACS_NEQUAL, TC_DESC("not-equal") },
+ { TACS_PLMINUS, TC_DESC("plus/minus") },
+ { TACS_S1, TC_DESC("scan line 1") },
+ { TACS_S3, TC_DESC("scan line 3") },
+ { TACS_S7, TC_DESC("scan line 7") },
+ { TACS_S9, TC_DESC("scan line 9") },
+ { TACS_BLOCK, TC_DESC("solid square block") },
+ { TACS_TTEE, TC_DESC("tee pointing down") },
+ { TACS_RTEE, TC_DESC("tee pointing left") },
+ { TACS_LTEE, TC_DESC("tee pointing right") },
+ { TACS_BTEE, TC_DESC("tee pointing up") },
+ { TACS_ULCORNER, TC_DESC("upper left corner") },
+ { TACS_URCORNER, TC_DESC("upper right corner") },
+ { TACS_VLINE, TC_DESC("vertical line") }
+ };
+
+static Term_t term_strings[] = { /* strings - termcap/terminfo elements */
+ { "ac", "acsc", TC_DESC("acs characters"), &tc_graphic_pairs },
+ { "bt", "cbt", TC_DESC("back tab")},
+ { "bl", "bel", TC_DESC("audible signal (bell)"), &tc_bl },
+ { "cr", "cr", TC_DESC("carriage return"), &tc_cr },
+ { "ZA", "cpi", TC_DESC("change number of characters per inch") },
+ { "ZB", "lpi", TC_DESC("change number of lines per inch") },
+ { "ZC", "chr", TC_DESC("change horizontal resolution") },
+ { "ZD", "cvr", TC_DESC("change vertical resolution") },
+ { "cs", "csr", TC_DESC("change region to line #1 to line #2"), &tc_cs },
+ { "rP", "rmp", TC_DESC("like ip but when in insert mode") },
+ { "ct", "tbc", TC_DESC("clear all tab stops") },
+ { "MC", "mgc", TC_DESC("clear right and left soft margins") },
+ { "cl", "clear", TC_DESC("clear screen and home cursor"), &tc_cl },
+ { "cb", "el1", TC_DESC("clear to beginning of line"), &tc_cb },
+ { "ce", "el", TC_DESC("clr eol"), &tc_ce },
+ { "cd", "ed", TC_DESC("clear to end of screen"), &tc_cd },
+ { "ch", "hpa", TC_DESC("horizontal position #1, absolute"), &tc_ch },
+ { "CC", "cmdch", TC_DESC("terminal settable cmd character in prototype !?") },
+ { "CW", "cwin", TC_DESC("define a window #1 from #2, #3 to #4, #5") },
+ { "cm", "cup", TC_DESC("move to row #1 columns #2"), &tc_cm },
+ { "do", "cud1", TC_DESC("down one line"), &tc_do },
+ { "ho", "home", TC_DESC("home cursor (if no cup)"), &tc_ho },
+ { "vi", "civis", TC_DESC("make cursor invisible"), &tc_vi },
+ { "le", "cub1", TC_DESC("move left one space"), &tc_le },
+ { "CM", "mrcup", TC_DESC("memory relative cursor addressing") },
+ { "ve", "cnorm", TC_DESC("make cursor appear normal (undo civis/cvvis)"), &tc_ve },
+ { "nd", "cuf1", TC_DESC("move right one space"), &tc_nd },
+ { "ll", "ll", TC_DESC("last line, first column (if no cup)"), &tc_ll },
+ { "up", "cuu1", TC_DESC("up one line"), &tc_up },
+ { "vs", "cvvis", TC_DESC("make cursor very visible"), &tc_vs },
+ { "ZE", "defc", TC_DESC("define a character") },
+ { "dc", "dch1", TC_DESC("delete character"), &tc_dc },
+ { "dl", "dl1", TC_DESC("delete line"), &tc_dl },
+ { "DI", "dial", TC_DESC("dial number #1") },
+ { "ds", "dsl", TC_DESC("disable status line") },
+ { "DK", "dclk", TC_DESC("display clock at (#1,#2)") },
+ { "hd", "hd", TC_DESC("half a line down") },
+ { "eA", "enacs", TC_DESC("enable alternate char set"), &tc_acs_enable },
+ { "as", "smacs", TC_DESC("enter alt charset mode"), &tc_acs_start },
+ { "SA", "smam", TC_DESC("turn on automatic margins"), &tc_am_on },
+ { "mb", "blink", TC_DESC("turn on blinking"), &tc_mb },
+ { "md", "bold", TC_DESC("turn on bold (extra bright) mode"), &tc_md },
+ { "ti", "smcup", TC_DESC("string to start programs using cup"), &tc_ti },
+ { "dm", "smdc", TC_DESC("enter delete mode") },
+ { "mh", "dim", TC_DESC("turn on half-bright mode") },
+ { "ZF", "swidm", TC_DESC("enter double-wide mode") },
+ { "ZG", "sdrfq", TC_DESC("enter draft-quality mode") },
+ { "im", "smir", TC_DESC("enter insert mode"), &tc_im },
+ { "ZH", "sitm", TC_DESC("enter italic mode"), &tc_ZH },
+ { "ZI", "slm", TC_DESC("start leftward carriage motion") },
+ { "ZJ", "smicm", TC_DESC("start micro-motion mode") },
+ { "ZK", "snlq", TC_DESC("enter NLQ mode") },
+ { "ZL", "snrmq", TC_DESC("enter normal-quality mode") },
+ { "mp", "prot", TC_DESC("turn on protected mode") },
+ { "mr", "rev", TC_DESC("turn on reverse video mode"), &tc_mr },
+ { "mk", "invis", TC_DESC("turn on blank mode (characters invisible)") },
+ { "ZM", "sshm", TC_DESC("enter shadow-print mode") },
+ { "so", "smso", TC_DESC("begin standout mode"), &tc_so },
+ { "ZN", "ssubm", TC_DESC("enter subscript mode") },
+ { "ZO", "ssupm", TC_DESC("enter superscript mode") },
+ { "us", "smul", TC_DESC("begin underline mode"), &tc_us },
+ { "ZP", "sum", TC_DESC("start upward carriage motion") },
+ { "SX", "smxon", TC_DESC("turn on xon/xoff handshaking") },
+ { "ec", "ech", TC_DESC("erase #1 characters"), &tc_ech },
+ { "ae", "rmacs", TC_DESC("exit alt charset mode"), &tc_acs_end },
+ { "RA", "rmam", TC_DESC("turn off automatic margins") },
+ { "me", "sgr0", TC_DESC("turn off all attributes"), &tc_me },
+ { "te", "rmcup", TC_DESC("strings to end programs using cup"), &tc_te },
+ { "ed", "rmdc", TC_DESC("end delete mode") },
+ { "ZQ", "rwidm", TC_DESC("end double-wide mode") },
+ { "ei", "rmir", TC_DESC("exit insert mode"), &tc_ei },
+ { "ZR", "ritm", TC_DESC("end italic mode"), &tc_ZR },
+ { "ZS", "rlm", TC_DESC("end left-motion mode") },
+ { "ZU", "rmicm", TC_DESC("end shadow-print mode") },
+ { "ZT", "rshm", TC_DESC("end micro-motion mode") },
+ { "se", "rmso", TC_DESC("exit standout mode"), &tc_se },
+ { "ZV", "rsubm", TC_DESC("exit_subscript_mode") },
+ { "ZW", "rsupm", TC_DESC("end superscript mode") },
+ { "ue", "rmul", TC_DESC("exit underline mode"), &tc_ue },
+ { "ZX", "rum", TC_DESC("end reverse character motion"), &tc_ZX },
+ { "RX", "rmxon", TC_DESC("turn off xon/xoff handshaking") },
+ { "PA", "pause", TC_DESC("pause for 2-3 seconds") },
+ { "fh", "hook", TC_DESC("flash switch hook") },
+ { "vb", "flash", TC_DESC("visible bell (may not move cursor)"), &tc_vb },
+ { "ff", "ff", TC_DESC("hardcopy terminal page eject") },
+ { "fs", "fsl", TC_DESC("return from status line") },
+ { "WG", "wingo", TC_DESC("go to window #1") },
+ { "HU", "hup", TC_DESC("hang-up phone") },
+ { "i1", "is1", TC_DESC("initialization string") },
+ { "is", "is2", TC_DESC("initialization string") },
+ { "i2", NULL, TC_DESC("secondary initialization string") },
+ { "i3", "is3", TC_DESC("initialization string") },
+ { "if", "if", TC_DESC("name of initialization file") },
+ { "iP", "iprog", TC_DESC("path name of program for initialization") },
+ { "Ic", "initc", TC_DESC("initialize color #1 to (#2,#3,#4)") },
+ { "Ip", "initp", TC_DESC("initialize color pair #1 to fg=(#2,#3,#4), bg=(#5,#6,#7)") },
+ { "ic", "ich1", TC_DESC("insert character"), &tc_ic },
+ { "al", "il1", TC_DESC("insert line"), &tc_al },
+ { "ip", "ip", TC_DESC("insert padding after inserted character") },
+ { "ke", "rmkx", TC_DESC("leave 'keyboard_transmit' mode"), &tc_ke },
+ { "ks", "smkx", TC_DESC("enter 'keyboard_transmit' mode"), &tc_ks },
+ { "l0", "lf0", TC_DESC("label on function key f0 if not f0") },
+ { "l1", "lf1", TC_DESC("label on function key f1 if not f1") },
+ { "l2", "lf10", TC_DESC("label on function key f2 if not f2") },
+ { "l3", "lf2", TC_DESC("label on function key f3 if not f3") },
+ { "l4", "lf3", TC_DESC("label on function key f4 if not f4") },
+ { "l5", "lf4", TC_DESC("label on function key f5 if not f5") },
+ { "l6", "lf5", TC_DESC("label on function key f6 if not f6") },
+ { "l7", "lf6", TC_DESC("label on function key f7 if not f7") },
+ { "l8", "lf7", TC_DESC("label on function key f8 if not f8") },
+ { "l9", "lf8", TC_DESC("label on function key f9 if not f9") },
+ { "la", "lf9", TC_DESC("label on function key f10 if not f10") },
+ { "Lf", "fln", TC_DESC("label format") },
+ { "LF", "rmln", TC_DESC("turn off soft labels") },
+ { "LO", "smln", TC_DESC("turn on soft labels") },
+ { "mo", "rmm", TC_DESC("turn off meta mode"), &tc_mo },
+ { "mm", "smm", TC_DESC("turn on meta mode (8th-bit on)"), &tc_mm },
+ { "ZY", "mhpa", TC_DESC("like column_address in micro mode") },
+ { "ZZ", "mcud1", TC_DESC("like cursor_down in micro mode") },
+ { "Za", "mcub1", TC_DESC("like cursor_left in micro mode") },
+ { "Zb", "mcuf1", TC_DESC("like cursor_right in micro mode") },
+ { "Zc", "mvpa", TC_DESC("like row_address in micro mode") },
+ { "Zd", "mcuu1", TC_DESC("like cursor_up in micro mode") },
+ { "nw", "nel", TC_DESC("newline (behave like cr followed by lf)") },
+ { "Ze", "porder", TC_DESC("match software bits to print-head pins") },
+ { "oc", "oc", TC_DESC("set all color pairs to the original ones"), &tc_oc },
+ { "op", "op", TC_DESC("set default pair to its original value"), &tc_op },
+ { "pc", "pad", TC_DESC("padding char (instead of null)"), &tc_pc },
+ { "DC", "dch", TC_DESC("delete #1 chars"), &tc_pDC },
+ { "DL", "dl", TC_DESC("parm_delete_line"), &tc_pDL },
+ { "DO", "cud", TC_DESC("down #1 lines"), &tc_pDO },
+ { "Zf", "mcud", TC_DESC("like parm down cursor in micro mode") },
+ { "IC", "ich", TC_DESC("insert #1 chars") },
+ { "SF", "indn", TC_DESC("scroll forward #1 lines"), &tc_pSF },
+ { "AL", "il", TC_DESC("parm insert line"), &tc_pAL },
+ { "LE", "cub", TC_DESC("move #1 chars to the left"), &tc_pBC },
+ { "Zg", "mcub", TC_DESC("Like parm left cursor in micro mode") },
+ { "RI", "cuf", TC_DESC("parm right cursor"), &tc_pRI },
+ { "Zh", "mcuf", TC_DESC("Like parm right cursor in micro mode") },
+ { "SR", "rin", TC_DESC("scroll back #1 lines"), &tc_pSR },
+ { "UP", "cuu", TC_DESC("up #1 lines"), &tc_pUP },
+ { "Zi", "mcuu", TC_DESC("Like parm_up_cursor in micro mode") },
+ { "pk", "pfkey", TC_DESC("program function key #1 to type string #2") },
+ { "pl", "pfloc", TC_DESC("program function key #1 to execute string #2") },
+ { "px", "pfx", TC_DESC("program function key #1 to transmit string #2") },
+ { "pn", "pln", TC_DESC("program label #1 to show string #2") },
+ { "ps", "mc0", TC_DESC("print contents of screen") },
+ { "pO", "mc5p", TC_DESC("turn on printer for #1 bytes") },
+ { "pf", "mc4", TC_DESC("turn off printer") },
+ { "po", "mc5", TC_DESC("turn on printer") },
+ { "PU", "pulse", TC_DESC("select pulse dialling") },
+ { "QD", "qdial", TC_DESC("dial number #1 without checking") },
+ { "RC", "rmclk", TC_DESC("remove clock") },
+ { "rp", "rep", TC_DESC("repeat char #1 #2 times"), &tc_rp},
+ { "RF", "rfi", TC_DESC("send next input char (for ptys)") },
+ { "rs", NULL, TC_DESC("terminal reset string"), &tc_rs},
+ { "r1", "rs1", TC_DESC("reset string") },
+ { "r2", "rs2", TC_DESC("reset string") },
+ { "r3", "rs3", TC_DESC("reset string") },
+ { "rf", "rf", TC_DESC("name of reset file") },
+ { "rc", "rc", TC_DESC("restore cursor to last position of sc") },
+ { "cv", "vpa", TC_DESC("vertical position #1 absolute"), &tc_cv },
+ { "sc", "sc", TC_DESC("save current cursor position") },
+ { "sf", "ind", TC_DESC("scroll text up"), &tc_sf },
+ { "sr", "ri", TC_DESC("scroll text down"), &tc_sr },
+ { "Zj", "scs", TC_DESC("select character set") },
+ { "sa", "sgr", TC_DESC("define video attributes #1-#9 (PG9)"), &tc_sa },
+ { "Sb", "setb", TC_DESC("set background (color)"), &tc_Color_Bg },
+ { "Zk", "smgb", TC_DESC("set bottom margin at current line") },
+ { "Zl", "smgbp", TC_DESC("set bottom margin at line #1 or #2 lines from bottom") },
+ { "SC", "sclk", TC_DESC("set clock, #1 hrs #2 mins #3 secs") },
+ { "sp", "scp", TC_DESC("set current color pair to #1") },
+ { "Sf", "setf", TC_DESC("set foreground (color)"), &tc_Color_Fg },
+ { "ML", "smgl", TC_DESC("set left soft margin") },
+ { "Zm", "smglp", TC_DESC("set left (right) margin at column #1 (#2)") },
+ { "MR", "smgr", TC_DESC("set right soft margin") },
+ { "Zn", "smgrp", TC_DESC("set right margin at column #1") },
+ { "st", "hts", TC_DESC("set a tab in every row, current columns") },
+ { "Zo", "smgt", TC_DESC("set top margin at current line") },
+ { "Zq", "smgtp", TC_DESC("start printing bit image braphics") },
+ { "wi", "wind", TC_DESC("current window is lines #1-#2 cols #3-#4") },
+ { "Zq", "sbim", TC_DESC("start bit image") },
+ { "Zr", "scsd", TC_DESC("start character set definition") },
+ { "Zs", "rbim", TC_DESC("stop printing bit image graphics") },
+ { "Zt", "rcsd", TC_DESC("end definition of character aet") },
+ { "Zu", "subcs", TC_DESC("list of subscriptable characters") },
+ { "Zv", "supcs", TC_DESC("list of superscriptable characters") },
+ { "ta", "ht", TC_DESC("tab to next 8-space hardware tab stop") },
+ { "Zw", "docr", TC_DESC("printing any of these chars causes CR") },
+ { "ts", "tsl", TC_DESC("move to status line") },
+ { "TO", "tone", TC_DESC("select touch tone dialing") },
+ { "uc", "uc", TC_DESC("underline char and move past it") },
+ { "hu", "hu", TC_DESC("half a line up") },
+ { "u0", "u0", TC_DESC("user string #0") },
+ { "u1", "u1", TC_DESC("user string #1") },
+ { "u2", "u2", TC_DESC("user string #2") },
+ { "u3", "u3", TC_DESC("user string #3") },
+ { "u4", "u4", TC_DESC("user string #4") },
+ { "u5", "u5", TC_DESC("user string #5") },
+ { "u6", "u6", TC_DESC("user string #6") },
+ { "u7", "u7", TC_DESC("user string #7") },
+ { "u8", "u8", TC_DESC("user string #8") },
+ { "u9", "u9", TC_DESC("user string #9") },
+ { "WA", "wait", TC_DESC("wait for dial-tone") },
+ { "XF", "xoffc", TC_DESC("XOFF character") },
+ { "XN", "xonc", TC_DESC("XON character") },
+ { "Zx", "zerom", TC_DESC("no motion for subsequent character") },
+
+ /*
+ * The following string capabilities are present in the SVr4.0 term
+ * structure, but were originally not documented in the man page.
+ */
+ { "S8", "scesa", TC_DESC("alternate escape for scancode emulation") },
+ { "Yv", "bicr", TC_DESC("move to beginning of same row") },
+ { "Zz", "binel", TC_DESC("move to next row of the bit image") },
+ { "Xy", "birep", TC_DESC("repeat bit image cell #1 #2 times") },
+ { "Zy", "csnm", TC_DESC("list of character set names") },
+ { "ci", "csin", TC_DESC("init sequence for multiple codesets") },
+ { "Yw", "colornm", TC_DESC("give name for color #1") },
+ { "Yx", "defbi", TC_DESC("define rectangualar bit image region") },
+ { "dv", "devt", TC_DESC("indicate language/codeset support") },
+ { "S1", "dispc", TC_DESC("display PC character") },
+ { "Yy", "endbi", TC_DESC("end a bit-image region") },
+ { "S2", "smpch", TC_DESC("enter PC character display mode") },
+ { "S4", "smsc", TC_DESC("enter PC scancode mode") },
+ { "S3", "rmpch", TC_DESC("exit PC character display mode") },
+ { "S5", "rmsc", TC_DESC("exit PC scancode mode") },
+ { "Gm", "getm", TC_DESC("curses should get button events") },
+ { "Km", "kmous", TC_DESC("mouse event has occurred") },
+ { "Mi", "minfo", TC_DESC("mouse status information") },
+ { "S6", "pctrm", TC_DESC("PC terminal options") },
+ { "xl", "pfxl", TC_DESC("program function key #1 to type string #2 and show string #3") },
+ { "RQ", "reqmp", TC_DESC("request mouse position") },
+ { "S7", "scesc", TC_DESC("escape for scancode emulation") },
+ { "s0", "s0ds", TC_DESC("shift to code set 0 (EUC set 0, ASCII)") },
+ { "s1", "s1ds", TC_DESC("shift to code set 1") },
+ { "s2", "s2ds", TC_DESC("shift to code set 2") },
+ { "s3", "s3ds", TC_DESC("shift to code set 3") },
+ { "AB", "setab", TC_DESC("set ANSI color background"), &tc_ANSI_Color_Bg },
+ { "AF", "setaf", TC_DESC("set ANSI color foreground"), &tc_ANSI_Color_Fg },
+ { "Yz", "setcolor", TC_DESC("change to ribbon color #1") },
+ { "ML", "smglr", TC_DESC("set both left and right margins to #1, #2") },
+ { "YZ", "slines", TC_DESC("set page length to #1 lines") },
+ { "MT", "smgtb", TC_DESC("sets both top and bottom margins to #1, #2") },
+
+ /*
+ * The XSI Curses standard added these. They are some post-4.1 versions
+ * of System V curses, e.g., Solaris 2.5 and IRIX 6.x. The ncurses term-
+ * cap names for them are invented; according to the XSI Curses standard,
+ * they have no termcap names. If your compiled terminfo entries use
+ * these, they may not be binary-compatible with System V terminfo
+ * entries after SVr4.1; beware!
+ */
+ { "Xh", "ehhlm", TC_DESC("enter horizontal highlight mode") },
+ { "Xl", "elhlm", TC_DESC("enter left highlight mode") },
+ { "Xo", "elohlm", TC_DESC("enter low highlight mode") },
+ { "Xr", "erhlm", TC_DESC("enter right highlight mode") },
+ { "Xt", "ethlm", TC_DESC("enter top highlight mode") },
+ { "Xv", "evhlm", TC_DESC("enter vertical highlight mode") },
+
+ /*
+ * Characters, Note: have only seen 'bx' under AIX, which must be ordered
+ * after "ac" for correct selection.
+ */
+ { "G1", NULL, TC_DESC("single upper right") },
+ { "G2", NULL, TC_DESC("single upper left") },
+ { "G3", NULL, TC_DESC("single lower left") },
+ { "G4", NULL, TC_DESC("single lower right") },
+ { "GC", NULL, TC_DESC("single intersection") },
+ { "GD", NULL, TC_DESC("tee pointing down") },
+ { "GH", NULL, TC_DESC("single horizontal line") },
+ { "GL", NULL, TC_DESC("tee pointing left") },
+ { "GR", NULL, TC_DESC("tee pointing right") },
+ { "GU", NULL, TC_DESC("tee pointing up") },
+ { "GV", NULL, TC_DESC("single vertical line") },
+ { "bx", NULL, TC_DESC("box chars primary set"), &tc_box_characters },
+
+ /*
+ * Others
+ */
+ { "cS", NULL, TC_DESC("change region to line #1 to line #2, alt form"), &tc_cS},
+ { "bc", NULL, TC_DESC("move left, if not ^H (old-style)"), &tc_bc},
+ { "nl", NULL, TC_DESC("use to move down") },
+ /* { "ko", NULL, TC_DESC("list of self-mapped keycaps") }, */
+ /* { "ma", NULL, TC_DESC("map arrow keys rogue(1) motion keys") }, */
+ { "ml", NULL, TC_DESC("memory lock above") },
+ { "mu", NULL, TC_DESC("memory unlock") }
+ };
+
+#if (XXX_KO)
+/*
+ ko capability, consists of a comma-separated capability list.
+ For each capability, it should be assumed there is a keycap
+ that sends the string which is the value of that capability.
+
+ String listing the other function keys the terminal has.
+
+ This is a very obsolete way of describing the same
+ information found in the `kH' ... `kT' keys.
+
+ The string contains a list of two-character termcap
+ capability names, separated by commas. The meaning is that
+ for each capability name listed, the terminal has a key which
+ sends the string which is the value of that capability.
+
+ For example, the value `:ko=cl, ll, sf, sr:' says that the
+ terminal has four function keys which mean "clear screen",
+ "home down", "scroll forward" and "scroll reverse
+ */
+static const struct {
+ const char *from;
+ const char *to;
+} ko_xlate[] = {
+ { "al", "kil1" }, /* insert line key */
+ { "bt", "kcbt" }, /* back tab */
+ { "cd", "ked" }, /* clear-to-eos key */
+ { "ce", "kel" }, /* clear-to-eol key */
+ { "cl", "kclr" }, /* clear key */
+ { "ct", "tbc" }, /* clear all tabs */
+ { "dc", "kdch1" }, /* delete char */
+ { "dl", "kdl1" }, /* delete line */
+ { "do", "kcud1" }, /* down key */
+ { "ei", "krmir" }, /* exit insert key */
+ { "ho", "khome" }, /* home key */
+ { "ic", "kich1" }, /* insert char key */
+ { "im", "kIC" }, /* insert-mode key */
+ { "le", "kcub1" }, /* le key */
+ { "nd", "kcuf1" }, /* nd key */
+ { "nl", "kent" }, /* new line key */
+ { "st", "khts" }, /* set-tab key */
+ { "ta", "kcan" }, /* cancel */
+ { "up", "kcuu1" }, /* up-arrow key */
+ };
+#endif /*XXX_KO*/
+
+
+static Term_t term_numbers[] = { /* numeric - termcap/terminfo elements */
+ /*
+ * standard
+ */
+ { "MW", "wnum", TC_DESC("max number of defineable windows") },
+ { "co", "cols", TC_DESC("number of columns"), &tn_co },
+ { "it", "it", TC_DESC("tabs initially every # spaces") },
+ { "Nl", "nlab", TC_DESC("number of labels") },
+ { "lh", "lh", TC_DESC("rows in each label") },
+ { "li", "lines", TC_DESC("number of lines on screen or page"), &tn_li },
+ { "lm", "lm", TC_DESC("lines of memory if > line, 0 means varies") },
+ { "lw", "lw", TC_DESC("columns in each label") },
+ { "ma", "ma", TC_DESC("max combined attributes") },
+ { "pb", "pb", TC_DESC("lowest baud rate needing padding") },
+ { "sg", "xmc", TC_DESC("number of blank chars left by smso or rmso"), &tn_sg },
+ { "vt", "vt", TC_DESC("virtual terminal number") },
+ { "ws", "wsl", TC_DESC("number of columns within status line") },
+
+ /*
+ * SRV 4.0 color
+ */
+ { "Co", "colors", TC_DESC("max color"), &tf_Colors },
+ { "pa", "pairs", TC_DESC("max of color-pairs"), &tf_Pairs },
+ { "NC", "ncv", TC_DESC("video attributes that cannot be used with colors"), &tn_NC },
+
+ /*
+ * The following numeric capabilities are present in the SVr4.0 term structure,
+ * but are not yet documented in the man page. They came in with SVr4's printer support.
+ */
+ { "BT", NULL, TC_DESC("number of buttons on the mouse") },
+
+ /*
+ * Padding times
+ */
+ { "dC", NULL, TC_DESC("msec of padding for carriage-return character") },
+ { "dN", NULL, TC_DESC("msec of padding for newline (linefeed) character") },
+ { "dB", NULL, TC_DESC("msec of padding for backspace character") },
+ { "dF", NULL, TC_DESC("msec of padding for formfeed character") },
+ { "dT", NULL, TC_DESC("msec of padding for tab character") }
+ };
+
+
+static Term_t term_keys[] = { /* keys - termcap/terminfo elements */
+ { "!1", "kSAV", TC_DESC("shifted save key") },
+ { "!2", "kSPD", TC_DESC("shifted suspend key") },
+ { "!3", "kUND", TC_DESC("shifted undo key"), TC_TOKEN(KEY_REDO) },
+ { "#1", "kHLP", TC_DESC("shifted help key") }, /* KEY_HELP */
+ { "#2", "kHOM", TC_DESC("shifted home key"), TC_TOKEN(MOD_SHIFT|KEY_HOME) },
+ { "#3", "kIC", TC_DESC("shifted insert-character key") },
+ { "#4", "kLFT", TC_DESC("shifted left-arrow key") },
+ { "%0", "krdo", TC_DESC("redo key"), TC_TOKEN(KEY_REDO) },
+ { "%1", "khlp", TC_DESC("help key"), TC_TOKEN(KEY_HELP) },
+ { "%2", "kmrk", TC_DESC("mark key") }, /* KEY_MARK */
+ { "%3", "kmsg", TC_DESC("message key") },
+ { "%4", "kmov", TC_DESC("move key") },
+ { "%5", "knxt", TC_DESC("next key"), TC_TOKEN(KEY_NEXT) },
+ { "%6", "kopn", TC_DESC("open key"), TC_TOKEN(KEY_OPEN) },
+ { "%7", "kopt", TC_DESC("options key"), TC_TOKEN(KEY_MENU) },
+ { "%8", "kprv", TC_DESC("previous key"), TC_TOKEN(KEY_PREV) },
+ { "%9", "kprt", TC_DESC("print key") }, /* KEY_PRINT */
+ { "%a", "kMSG", TC_DESC("shifted message key") },
+ { "%b", "kMOV", TC_DESC("shifted move key") },
+ { "%c", "kNXT", TC_DESC("shifted next key") },
+ { "%d", "kOPT", TC_DESC("shifted options key") },
+ { "%e", "kPRV", TC_DESC("shifted previous key") },
+ { "%f", "kPRT", TC_DESC("shifted print key") },
+ { "%g", "kRDO", TC_DESC("shifted redo key") },
+ { "%h", "kRPL", TC_DESC("shifted replace key") },
+ { "%i", "kRIT", TC_DESC("shifted right-arrow key") },
+ { "%j", "kRES", TC_DESC("shifted resume key") },
+ { "&0", "kCAN", TC_DESC("shifted cancel key") },
+ { "&1", "kref", TC_DESC("reference key") },
+ { "&2", "krfr", TC_DESC("refresh key") }, /* KEY_REFRESH */
+ { "&3", "krpl", TC_DESC("replace key"), TC_TOKEN(KEY_REPLACE) },
+ { "&4", "krst", TC_DESC("restart key") },
+ { "&5", "kres", TC_DESC("resume key") },
+ { "&6", "ksav", TC_DESC("save key"), TC_TOKEN(KEY_SAVE) },
+ { "&7", "kspd", TC_DESC("suspend key") },
+ { "&8", "kund", TC_DESC("undo key"), TC_TOKEN(KEY_UNDO_CMD) },
+ { "&9", "kBEG", TC_DESC("shifted begin key") },
+ { "*0", "kFND", TC_DESC("shifted find key") },
+ { "*1", "kCMD", TC_DESC("shifted command key") },
+ { "*2", "kCPY", TC_DESC("shifted copy key") },
+ { "*3", "kCRT", TC_DESC("shifted create key") },
+ { "*4", "kDC", TC_DESC("shifted delete-char") },
+ { "*5", "kDL", TC_DESC("shifted delete-line key") },
+ { "*6", "kslt", TC_DESC("select key") },
+ { "*7", "kEND", TC_DESC("shifted end key"), TC_TOKEN(MOD_SHIFT|KEY_END) },
+ { "*8", "kEOL", TC_DESC("shifted clear-to-end-of-line key") },
+ { "*9", "kEXT", TC_DESC("shifted exit key") },
+ { "@0", "kfnd", TC_DESC("find key"), TC_TOKEN(KEY_SEARCH) },
+ { "@1", "kbeg", TC_DESC("begin key") },
+ { "@2", "kcan", TC_DESC("cancel key"), TC_TOKEN(KEY_CANCEL) },
+ { "@3", "kclo", TC_DESC("close key") },
+ { "@4", "kcmd", TC_DESC("command key"), TC_TOKEN(KEY_COMMAND) },
+ { "@5", "kcpy", TC_DESC("copy key"), TC_TOKEN(KEY_COPY_CMD) },
+ { "@6", "kcrt", TC_DESC("create key") },
+ { "@7", "kend", TC_DESC("end key"), TC_TOKEN(KEY_END) },
+ { "@8", "kent", TC_DESC("enter/send key") },
+ { "@9", "kext", TC_DESC("exit key"), TC_TOKEN(KEY_EXIT) },
+ { "F1", "kf11", TC_DESC("F11 function key"), TC_TOKEN(F(11)) },
+ { "F2", "kf12", TC_DESC("F12 function key"), TC_TOKEN(F(12)) },
+ { "F3", "kf13", TC_DESC("F13 function key") /*, TC_TOKEN(F(13))*/ },
+ { "F4", "kf14", TC_DESC("F14 function key") /*, TC_TOKEN(F(14))*/ },
+ { "F5", "kf15", TC_DESC("F15 function key") /*, TC_TOKEN(F(15))*/ },
+ { "F6", "kf16", TC_DESC("F16 function key") /*, TC_TOKEN(F(16))*/ },
+ { "F7", "kf17", TC_DESC("F17 function key") /*, TC_TOKEN(F(17))*/ },
+ { "F8", "kf18", TC_DESC("F18 function key") /*, TC_TOKEN(F(18))*/ },
+ { "F9", "kf19", TC_DESC("F19 function key") /*, TC_TOKEN(F(19))*/ },
+ { "FA", "kf20", TC_DESC("F20 function key") /*, TC_TOKEN(F(20))*/ },
+ { "FB", "kf21", TC_DESC("F21 function key") },
+ { "FC", "kf22", TC_DESC("F22 function key") },
+ { "FD", "kf23", TC_DESC("F23 function key") },
+ { "FE", "kf24", TC_DESC("F24 function key") },
+ { "FF", "kf25", TC_DESC("F25 function key") },
+ { "FG", "kf26", TC_DESC("F26 function key") },
+ { "FH", "kf27", TC_DESC("F27 function key") },
+ { "FI", "kf28", TC_DESC("F28 function key") },
+ { "FJ", "kf29", TC_DESC("F29 function key") },
+ { "FK", "kf30", TC_DESC("F30 function key") },
+ { "FL", "kf31", TC_DESC("F31 function key") },
+ { "FM", "kf32", TC_DESC("F32 function key") },
+ { "FN", "kf33", TC_DESC("F33 function key") },
+ { "FO", "kf34", TC_DESC("F34 function key") },
+ { "FP", "kf35", TC_DESC("F35 function key") },
+ { "FQ", "kf36", TC_DESC("F36 function key") },
+ { "FR", "kf37", TC_DESC("F37 function key") },
+ { "FS", "kf38", TC_DESC("F38 function key") },
+ { "FT", "kf39", TC_DESC("F39 function key") },
+ { "FU", "kf40", TC_DESC("F40 function key") },
+ { "FV", "kf41", TC_DESC("F41 function key") },
+ { "FW", "kf42", TC_DESC("F42 function key") },
+ { "FX", "kf43", TC_DESC("F43 function key") },
+ { "FY", "kf44", TC_DESC("F44 function key") },
+ { "FZ", "kf45", TC_DESC("F45 function key") },
+ { "Fa", "kf46", TC_DESC("F46 function key") },
+ { "Fb", "kf47", TC_DESC("F47 function key") },
+ { "Fc", "kf48", TC_DESC("F48 function key") },
+ { "Fd", "kf49", TC_DESC("F49 function key") },
+ { "Fe", "kf50", TC_DESC("F50 function key") },
+ { "Ff", "kf51", TC_DESC("F51 function key") },
+ { "Fg", "kf52", TC_DESC("F52 function key") },
+ { "Fh", "kf53", TC_DESC("F53 function key") },
+ { "Fi", "kf54", TC_DESC("F54 function key") },
+ { "Fj", "kf55", TC_DESC("F55 function key") },
+ { "Fk", "kf56", TC_DESC("F56 function key") },
+ { "Fl", "kf57", TC_DESC("F57 function key") },
+ { "Fm", "kf58", TC_DESC("F58 function key") },
+ { "Fn", "kf59", TC_DESC("F59 function key") },
+ { "Fo", "kf60", TC_DESC("F60 function key") },
+ { "Fp", "kf61", TC_DESC("F61 function key") },
+ { "Fq", "kf62", TC_DESC("F62 function key") },
+ { "Fr", "kf63", TC_DESC("F63 function key") },
+ { "K1", "ka1", TC_DESC("upper left of keypad"), TC_TOKEN(KEYPAD_7) },
+ { "K2", "kb2", TC_DESC("center of keypad"), TC_TOKEN(KEYPAD_9) },
+ { "K3", "ka3", TC_DESC("upper right of key-pad"), TC_TOKEN(KEYPAD_5) },
+ { "K4", "kc1", TC_DESC("lower left of keypad"), TC_TOKEN(KEYPAD_1) },
+ { "K5", "kc3", TC_DESC("lower right of key-pad"), TC_TOKEN(KEYPAD_3) },
+ { "k0", "kf0", TC_DESC("F0 function key"), TC_TOKEN(F(10)) },
+ { "k1", "kf1", TC_DESC("F1 function key"), TC_TOKEN(F(1)) },
+ { "k2", "kf2", TC_DESC("F2 function key"), TC_TOKEN(F(2)) },
+ { "k3", "kf3", TC_DESC("F3 function key"), TC_TOKEN(F(3)) },
+ { "k4", "kf4", TC_DESC("F4 function key"), TC_TOKEN(F(4)) },
+ { "k5", "kf5", TC_DESC("F5 function key"), TC_TOKEN(F(5)) },
+ { "k6", "kf6", TC_DESC("F6 function key"), TC_TOKEN(F(6)) },
+ { "k7", "kf7", TC_DESC("F7 function key"), TC_TOKEN(F(7)) },
+ { "k8", "kf8", TC_DESC("F8 function key"), TC_TOKEN(F(8)) },
+ { "k9", "kf9", TC_DESC("F9 function key"), TC_TOKEN(F(9)) },
+ { "k;", "kf10", TC_DESC("F10 function key"), TC_TOKEN(F(10)) },
+ { "kA", "kil1", TC_DESC("insert-line key") },
+ { "kB", "kcbt", TC_DESC("back-tab key"), TC_TOKEN(BACK_TAB) },
+ { "kC", "kclr", TC_DESC("clear-screen or erase key") },
+ { "kD", "kdch1", TC_DESC("delete-character key"), TC_TOKEN(KEY_DEL) },
+ { "kE", "kel", TC_DESC("clear-to-end-of-line key") },
+ { "kF", "kind", TC_DESC("scroll-forward key") },
+ { "kH", "kll", TC_DESC("lower-left key (home down)"), TC_TOKEN(KEY_END) },
+ { "kI", "kich1", TC_DESC("insert-character key"), TC_TOKEN(KEY_INS) },
+ { "kL", "kdl1", TC_DESC("delete-line key") },
+ { "kM", "krmir", TC_DESC("sent by rmir or smi rin insert mode") },
+ { "kN", "knp", TC_DESC("next-page key"), TC_TOKEN(KEY_PAGEDOWN) },
+ { "kP", "kpp", TC_DESC("previous-page key"), TC_TOKEN(KEY_PAGEUP) },
+ { "kR", "kri", TC_DESC("scroll-backward key") },
+ { "kS", "ked", TC_DESC("clear-to-end-of-screen key") },
+ { "kT", "khts", TC_DESC("set-tab key") },
+ { "ka", "ktbc", TC_DESC("clear-all-tabs key") },
+ { "kb", "kbs", TC_DESC("backspace key"), TC_TOKEN(CTRL_H) },
+ { "kd", "kcud1", TC_DESC("down-arrow key"), TC_TOKEN(KEY_DOWN) },
+ { "kh", "khome", TC_DESC("home key"), TC_TOKEN(KEY_HOME) },
+ { "kl", "kcub1", TC_DESC("left-arrow key"), TC_TOKEN(KEY_LEFT) },
+ { "kr", "kcuf1", TC_DESC("right-arrow key"), TC_TOKEN(KEY_RIGHT) },
+ { "kt", "kctab", TC_DESC("clear-tab key") },
+ { "ku", "kcuu1", TC_DESC("up-arrow key"), TC_TOKEN(KEY_UP) },
+ };
+
+static Term_t term_flags[] = { /* boolean - termcap/terminfo elements */
+ { "5i", "mc5i", TC_DESC("printer won't echo on screen") },
+ { "HC", "chts", TC_DESC("cursor is hard to see") },
+ { "LP", NULL, TC_DESC("last column of last line will not scroll"), TC_TOKEN(&tf_LP) },
+ { "MT", NULL, TC_DESC("has meta key") }, /* TODO */
+ { "ND", "ndscr", TC_DESC("scrolling region is non-destructive") },
+ { "NL", NULL, TC_DESC("move down with \\n"), TC_TOKEN(&tf_NL) },
+ { "NP", "npc", TC_DESC("pad character does not exist"), TC_TOKEN(&tf_npc) },
+ { "NR", "nrrmc", TC_DESC("smcup does not reverse rmcup") },
+ { "YA", "xhpa", TC_DESC("only positive motion for hpa/mhpa caps") },
+ { "YB", "crxm", TC_DESC("using cr turns off micro mode") },
+ { "YC", "daisy", TC_DESC("printer needs operator to change character set") },
+ { "YD", "xvpa", TC_DESC("only positive motion for vpa/mvpa caps") },
+ { "YE", "sam", TC_DESC("printing in last column causes cr") },
+ { "YF", "cpix", TC_DESC("changing character pitch changes resolution") },
+ { "YG", "lpix", TC_DESC("changing line pitch changes resolution") },
+ { "am", "am", TC_DESC("terminal has automatic margins"), TC_TOKEN(&tf_am) },
+ { "be", NULL, TC_DESC("back color erase"), TC_TOKEN(&tf_be) },
+ { "bs", NULL, TC_DESC("uses ^H to move left"), TC_TOKEN(&tf_bs) },
+ { "bw", "bw", TC_DESC("cub1 wraps from column 0 to last column") },
+ { "cc", "ccc", TC_DESC("terminal can re-define existing colors") },
+ { "da", "da", TC_DESC("display may be retained above the screen") },
+ { "db", "db", TC_DESC("display may be retained below the screen") },
+ { "eo", "eo", TC_DESC("can erase overstrikes with a blank") },
+ { "es", "eslok", TC_DESC("escape can be used on the status line") },
+ { "gn", "gn", TC_DESC("generic line type"), TC_TOKEN(&tf_gn) },
+ { "hc", "hc", TC_DESC("hardcopy terminal"), TC_TOKEN(&tf_hc) },
+ { "hl", "hls", TC_DESC("terminal uses only HLS color notation (tektronix)") },
+ { "hs", "hs", TC_DESC("has extra status line") },
+ { "hz", "hz", TC_DESC("can't print ~'s (hazeltine)"), TC_TOKEN(&tf_hz) },
+ { "in", "in", TC_DESC("insert mode distinguishes nulls") },
+ { "km", "km", TC_DESC("Has a meta key, sets msb high"), TC_TOKEN(&tf_km) },
+ { "mi", "mir", TC_DESC("safe to move while in insert mode") },
+ { "ms", "msgr", TC_DESC("safe to move while in standout/underline mode"), TC_TOKEN(&tf_ms) },
+ { "nc", NULL, TC_DESC("no way to go to start of line") },
+ { "ns", NULL, TC_DESC("crt cannot scroll") },
+ { "nx", "nxon", TC_DESC("padding won't work, xon/xoff required"), TC_TOKEN(&tf_xonoff) },
+ { "os", "os", TC_DESC("terminal can overstrike") },
+ { "pt", NULL, TC_DESC("has 8-char tabs invoked with ^I") },
+ { "ul", "ul", TC_DESC("underline character overstrikes") },
+ { "ut", "bce", TC_DESC("screen erased with background color"), TC_TOKEN(&tf_ut) },
+ { "xb", "xsb", TC_DESC("beehive (f1=escape, f2=ctrl C)") },
+ { "xn", "xenl", TC_DESC("newline ignored after 80 cols (concept)"), TC_TOKEN(&tf_xn) },
+ { "xo", NULL, TC_DESC("terminal uses xon/xoff handshaking"), TC_TOKEN(&tf_xonoff) },
+ { "xr", "xon", TC_DESC("return clears the line") },
+ { "xs", "xhp", TC_DESC("standout not erased by overwriting (hp)"), TC_TOKEN(&tf_xs) },
+ { "xt", "xt", TC_DESC("tabs destructive, magic so char (Telray 1061)"), TC_TOKEN(&tf_xt) }
+ };
+
+
+static const unsigned ansicolor_map[] = { /* BRIEF -> ANSI color map */
+/* BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, WHITE */
+ 0, 4, 2, 6, 1, 5, 3, 7,
+ 8, 12, 10, 14, 9, 13, 11, 15
+ };
+
+
+static const struct colormap { /* BRIEF -> XTERM color map */
+ int ident;
+ int c8;
+ int c16;
+ int c16_pc;
+ int c88_compat; /* 8/16 color compat */
+ int c256_compat; /* 8/16 color compat */
+ int c88;
+ int c256;
+
+} color_map[] = {
+ /* Ident 8 16 16/PC 88/C 256/C 88 256 */
+ { BLACK, 0, 0, 0, 0, 0, 0, 0 },
+ { BLUE, 4, 4, 1, 1, 4, 12, 12 },
+ { GREEN, 2, 2, 2, 2, 2, 10, 10 },
+ { CYAN, 6, 6, 3, 3, 6, 14, 14 },
+ { RED, 1, 1, 4, 4, 1, 9, 9 },
+ { MAGENTA, 5, 5, 5, 5, 5, 13, 13 },
+ { BROWN, 3, 3, 6, 6, 130, 32, 130 },
+ { WHITE, 7, 7, 7, 7, 7, 84, 248 },
+
+ { GREY, 0, 8, 8, 8, 8, 7, 7 },
+ { LTBLUE, 4, 12, 9, 12, 12, 43, 81 },
+ { LTGREEN, 2, 10, 10, 10, 10, 61, 121 },
+ { LTCYAN, 6, 14, 11, 14, 14, 63, 159 },
+ { LTRED , 1, 9, 12, 9, 9, 74, 224 },
+ { LTMAGENTA, 5, 13, 13, 13, 13, 75, 225 },
+ { YELLOW , 3, 11, 14, 11, 11, 11, 11 },
+ { LTWHITE, 7, 15, 15, 15, 15, 1, 15 },
+
+ { DKGREY, 0, 0, 0, 0, 0, 82, 242 },
+ { DKBLUE, 4, 4, 1, 1, 4, 4, 4 },
+ { DKGREEN, 2, 2, 2, 2, 2, 2, 2 },
+ { DKCYAN, 6, 6, 3, 3, 6, 6, 6 },
+ { DKRED, 1, 1, 4, 4, 1, 1, 1 },
+ { DKMAGENTA, 5, 5, 5, 5, 5, 5, 5 },
+ { DKYELLOW, 3, 3, 6, 6, 130, 72, 130 },
+ { LTYELLOW, 3, 11, 14, 11, 11, 78, 229 },
+
+ { COLOR_NONE, -1, -1, -1, -1, -1, -1, -1 }
+ };
+
+/*
+ * Scroll window
+ */
+static int tt_top = -1; /* Top of scroll region. */
+static int tt_bot = -1; /* Bottom of scroll region. */
+
+/*
+ * Color information
+ */
+static int tt_colors = 8; /* color depth (-1 unknown) */
+
+static int tt_defaultfg = NOCOLOR;
+static int tt_defaultbg = NOCOLOR;
+
+static int tt_fg = NOCOLOR; /* foreground color */
+static int tt_bg = NOCOLOR; /* background color */
+static int tt_style; /* text standout/underline mode */
+
+static int tt_active = 0; /* display status */
+static int tt_cursor = 0; /* cursor status */
+
+static vbyte_t tt_hue = 0; /* current attribute */
+
+ /* BRIEF -> TERM-COLORS */
+static int tt_colormap[COLOR_NONE + 1];
+
+
+/* Function: ttinit
+ * Initialize the terminal when the editor gets started up.
+ *
+ * Calling Sequence:
+ *> ttinit
+ *> -> term_init
+ *> ttopen
+ *> -> term_open
+ *> ttready
+ *> -> term_ready
+ *> macro tty/
+ *> [ttfeature]
+ *> ttdisplay
+ *> -> term_display
+ *> [ttfeature]
+ *
+ *> ttfeature
+ *> ttprocess
+ *> -> term_control
+ *> ttwinch
+ *> -> term_control
+ *
+ *> ttclose
+ *> -> term_close
+ *
+ * Parameters:
+ * none.
+ *
+ * Configuration:
+ *
+ * Terminal identification.
+ *
+ * o TERM -
+ * General terminal identification.
+ * o KONSOLE_DCOP or KONSOLE_DBUS_SESSION -
+ * kconsole identification.
+ * o XTERM_VERSION -
+ * xterm version.
+ * o LINES/COLUMNS -
+ * Terminal size.
+ *
+ * Terminal capabilities.
+ *
+ * o COLORTERM_BCE -
+ * Assume BCE capabilities.
+ * o COLORTERM -
+ * slang style color terminal configuration, if set color assumed.
+ * o NCURSES_NO_UTF8_ACS -
+ * When running in a UTF-8 locale several terminals (including Linux console and GNU screen)
+ * ignore alternative character selection. If set use unicode box drawing characters in all
+ * cases.
+ * o NCURSES_ASSUMED_COLORS -
+ * Foreground and background colors.
+ * o COLORFGBG -
+ * rxvt/mrxvt terminal default color specification.
+ * o DEFAULT_COLORS -
+ * Default colors.
+ *
+ * Returns:
+ * nothing.
+ */
+void
+ttinit(void)
+{
+ const char *term;
+
+ trace_log("ttinit()\n");
+
+ /*
+ * profile
+ */
+ x_scrfn.scr_open = term_open;
+ x_scrfn.scr_ready = term_ready;
+ x_scrfn.scr_feature = term_feature;
+ x_scrfn.scr_display = term_display;
+ x_scrfn.scr_control = term_control;
+ x_scrfn.scr_close = term_close;
+
+ x_scrfn.scr_move = term_move;
+ x_scrfn.scr_cursor = term_cursor;
+ x_scrfn.scr_winch = term_sizeget;
+
+ x_scrfn.scr_names = term_names;
+ x_scrfn.scr_beep = term_beep;
+
+ x_scrfn.scr_clear = term_clear;
+ x_scrfn.scr_print = NULL;
+ x_scrfn.scr_putc = term_putc;
+ x_scrfn.scr_flush = term_flush;
+
+ x_scrfn.scr_insl = term_insl;
+ x_scrfn.scr_dell = term_dell;
+ x_scrfn.scr_eeol = term_eeol;
+ x_scrfn.scr_repeat = term_repeat;
+
+ term = ttisetup();
+
+ /*
+ * build attributes
+ */
+ if (0 == strncmp(term, "linux", 5)) { /* linux console */
+ t_attributes = TA_LINUX | TA_DARK;
+
+ } else if (0 == strncmp(term, "cygwin", 5)) {
+ const char *cygwin = ggetenv("CYGWIN");
+
+ if (cygwin) {
+ trace_log("\tCYGWIN:%s\n", cygwin);
+
+ if (strstr(cygwin, "codepage:oem")) {
+ if (xf_disptype < 0) { /* 8bit terminal */
+ xf_disptype = DISPTYPE_8BIT;
+ }
+ x_pt.pt_codepage = 850;
+
+ } else if (strstr(cygwin, "codepage:utf8")) {
+ if (xf_disptype < 0) { /* UTF8 enabled */
+ xf_disptype = DISPTYPE_UTF8;
+ }
+ }
+ }
+ t_attributes = TA_CYGWIN|TA_XTERMLIKE|TA_DARK;
+
+#if defined(linux)
+ } else if (0 == strncmp(term, "con", 3)) { /* console, con80x25 etc */
+ t_attributes = TA_LINUX|TA_DARK;
+#endif
+
+ } else if (0 == strncmp(term, "konsole", 7) ||
+ getenv("KONSOLE_DCOP") || getenv("KONSOLE_DBUS_SESSION")) {
+ t_attributes = TA_KONSOLE | TA_XTERMLIKE;
+
+ } else if (0 == strncmp(term, "screen", 6)) {
+ t_attributes = TA_SCREEN;
+ if (0 == strcmp(term, "screen.linux")) {
+ t_attributes |= TA_DARK;
+ }
+
+ } else if (0 == strcmp(term, "putty")) {
+ t_attributes |= TA_DARK;
+
+ } else if (strcmp(term, "vt52") != 0 && /* vt100+ */
+ term[0] == 'v' && term[1] == 't' && term[2] >= '1' && term[2] <= '9') {
+ t_attributes = TA_VT100LIKE;
+
+ } else if (term_xtermlike(term)) { /* eg. xterm-color */
+ t_attributes = TA_XTERM | TA_XTERMLIKE;
+#if defined(__CYGWIN__)
+ if (ggetenv("COMSPEC")) {
+ t_attributes |= TA_DARK; /* assume cmd/mintty */
+ }
+#endif /*__CYGWIN__*/
+ }
+
+ if (hasfeature(term, "rv")) {
+ t_attributes |= TA_LIGHT; /* rv = reverse video (black on white) */
+
+ } else if (hasfeature(term, "m") || hasfeature(term, "mono")) {
+ t_attributes |= TA_MONO; /* m = monochrome, suppress color support */
+ }
+
+ trace_log("terminal: %s (%s%s%s%s%s%s%s%s)\n", term,
+ (t_attributes & TA_LINUX ? "linux," : ""),
+ (t_attributes & TA_CYGWIN ? "cygwin," : ""),
+ (t_attributes & TA_VT100LIKE ? "vt100like," : ""),
+ (t_attributes & TA_XTERM ? "xterm," : ""),
+ (t_attributes & TA_XTERMLIKE ? "xtermlike," : ""),
+ (t_attributes & TA_LIGHT ? "light," : ""),
+ (t_attributes & TA_DARK ? "dark," : ""),
+ (t_attributes & TA_MONO ? "mono," : ""));
+
+ /*
+ * Load termcap values.
+ */
+ {
+ unsigned i, fkeys = 0;
+ const char *cp;
+
+ trace_log("termcap:\n");
+
+ trace_log(" General:\n");
+ for (i = 0; i < (sizeof(term_strings)/sizeof(term_strings[0])); i++) {
+ /*
+ * string values
+ */
+ const Term_t *ti = term_strings + i;
+ const char *name = ttiname(ti);
+
+ if (name && NULL != (cp = ttigetstr(ti))) {
+ const char **token = term_strings[i].token;
+
+ term_strings[i].value.i_str = cp;
+ if (token) {
+ *token = cp;
+ }
+ trace_log("\t%-50s%c %-5s : %s\n", term_strings[i].comment,
+ (token ? '*' : ' '), name, c_string(cp));
+
+ if (token == &tc_graphic_pairs) {
+ acs_dump(cp);
+ x_pt.pt_attributes |= TF_AGRAPHICCHARACTERS;
+
+ } else if (token == &tc_box_characters) {
+ const char *t_acs;
+
+ if (NULL == tc_graphic_pairs &&
+ (NULL != (t_acs = acs_box_characters(cp)))) {
+ acs_dump(t_acs);
+ tc_graphic_pairs = t_acs;
+ x_pt.pt_attributes |= TF_AGRAPHICCHARACTERS;
+ }
+ }
+ }
+ }
+
+ fkeys = 0;
+ trace_log(" Keys:\n");
+ for (i = 0; i < (sizeof(term_keys)/sizeof(term_keys[0])); ++i) {
+ /*
+ * keys
+ */
+ const Term_t *ti = term_keys + i;
+ const char *name = ttiname(ti);
+
+ if (name && NULL != (cp = ttigetstr(ti))) {
+ const size_t kcode = (size_t)term_keys[i].token;
+
+ term_keys[i].value.i_str = cp; /* loaded later by ttkeys() */
+
+ trace_log("\t%-50s%c %-5s : %s\n", term_keys[i].comment,
+ (kcode ? '*' : ' '), name, c_string(cp));
+
+ if (kcode >= F(1) && kcode <= F(10)) {
+ ++fkeys;
+ }
+ }
+ }
+
+ if (fkeys >= 10) { /* have all 10 function keys */
+ x_pt.pt_attributes |= TF_AFUNCTIONKEYS;
+ }
+
+ trace_log(" Numeric:\n");
+ for (i = 0; i < (sizeof(term_numbers)/sizeof(term_numbers[0])); ++i) {
+ /*
+ * numbers
+ */
+ const Term_t *ti = term_numbers + i;
+ const char *name = ttiname(ti);
+
+ if (name) {
+ term_numbers[i].value.i_val = ttigetnum(ti);
+ if (term_numbers[i].token) {
+ *((int *)term_numbers[i].token) = term_numbers[i].value.i_val;
+ }
+ trace_log("\t%-50s%c %-5s : %d\n", term_numbers[i].comment,
+ (term_numbers[i].token ? '*' : ' '), name, term_numbers[i].value.i_val);
+ }
+ }
+
+ trace_log(" Boolean/Flags:\n");
+ for (i = 0; i < (sizeof(term_flags)/sizeof(term_flags[0])); ++i) {
+ /*
+ * flags
+ */
+ const Term_t *ti = term_flags + i;
+ const char *name = ttiname(ti);
+
+ if (name) {
+ term_flags[i].value.i_val = ttigetflag(ti);
+ if (term_flags[i].token) {
+ *((int *)term_flags[i].token) = term_flags[i].value.i_val;
+ }
+ trace_log("\t%-50s%c %-5s : %d\n", term_flags[i].comment,
+ (term_flags[i].token ? '*' : ' '), name, term_flags[i].value.i_val);
+ }
+ }
+ }
+
+ /* color */
+ term_fgbg();
+
+ if (NULL != ggetenv("COLORTERM_BCE")) {
+ tf_be = 1; /* slang compat override */
+ }
+
+ if (NULL == tc_Color_Fg || NULL == tc_Color_Fg) {
+ if (tc_ANSI_Color_Fg && tc_ANSI_Color_Bg) {
+ tc_Color_Fg = tc_ANSI_Color_Fg;
+ tc_Color_Bg = tc_ANSI_Color_Bg;
+ }
+ }
+
+ /* fixup defective termcap/terminfo databases */
+ if (NULL == tc_graphic_pairs &&
+ (t_attributes & TA_VT100LIKE)) { /* VT1xx */
+ tc_acs_start = "\016";
+ tc_acs_end = "\017";
+ tc_acs_enable = "\033)0";
+ }
+
+ if (NULL == tc_graphic_pairs &&
+ strncmp(term, "aixterm", 7) == 0) { /* aixterm (VT102) */
+ tc_acs_start = "\016";
+ tc_acs_end = "\017";
+ tc_acs_enable = "\033(B\033)0";
+ }
+
+ if (tc_graphic_pairs && NULL == tc_acs_start) {
+ tc_acs_start = "\016";
+ tc_acs_end = "\017";
+ }
+ /* VT2xx+ */
+ if (((t_attributes & TA_VT100LIKE) && term[2] != '1') ||
+ (t_attributes & (TA_LINUX|TA_XTERMLIKE)) ) {
+ if (NULL == tc_pDL) tc_pDL = "\033[%dM";
+ if (NULL == tc_pAL) tc_pAL = "\033[%dL";
+ if (NULL == tc_cm) tc_cm = "\033[%i%d;%dH";
+ }
+
+ if (t_attributes & (TA_LINUX|TA_XTERM)) { /* VT2xx */
+ if (NULL == tc_cb) tc_cb = "\033[1K";
+ if (NULL == tc_ce) tc_ce = "\033[K";
+ }
+
+ /* stand-out mode equiv checks */
+ if (tc_se) {
+ if (tc_ZH && 0 == strcmp(tc_ZH, tc_se)) {
+ tc_ZH = tc_se;
+
+ } else if (NULL == tc_ZH) {
+ tc_mr = NULL; /* ignore or assume same as 'se' */
+ }
+
+ if (tc_ue && 0 == strcmp(tc_us, tc_se)) {
+ tc_ue = tc_se;
+ }
+
+ if (tc_ZR && 0 == strcmp(tc_ZR, tc_se)) {
+ tc_ZR = tc_se;
+ }
+ }
+
+ if (NULL == tc_do && tf_NL) {
+ tc_do = "\n";
+ } else if (tc_do && tc_do[0] == '\n' && !tf_NL) {
+ tc_do = NULL;
+ }
+
+ if (NULL == tc_le && NULL == tc_bc &&
+ (tf_bs || (t_attributes & TA_XTERMLIKE))) {
+ tc_bc = "\b";
+ }
+
+ /*
+ * Verify min requirements
+ */
+ if (tf_gn) {
+ fprintf(stderr, "Generic terminal '%s', you have not specified your real terminal type.\n", term);
+ exit(1);
+
+ } else if (tf_hc) {
+ fprintf(stderr, "Hard copy terminal '%s', not supported.\n", term);
+ exit(1);
+
+ } else if (tf_xonoff) {
+ fprintf(stderr, "Terminal '%s' requires xon/xoff, not supported (try --curses).\n", term);
+ exit(1);
+
+ } else if (tn_sg >= 1) {
+ fprintf(stderr, "Terminal '%s' using magic-cookie's, not supported (try --curses).\n", term);
+ exit(1);
+
+ } else if (NULL == tc_cm && (NULL == tc_cv || NULL == tc_ch)) {
+ fprintf(stderr, "Terminal '%s' missing cursor move capabilities, not supported.\n", term);
+ exit(1);
+
+ } else if (tf_xs >= 1 || tf_xt >= 1) {
+ fprintf(stderr, "Terminal '%s' requires old-style attribute handling, not supported.\n", term);
+ exit(1);
+ }
+
+#if defined(__CYGWIN__)
+ /*
+ * o retrieve display code page
+ * o plus enable tf_xn as the terminal cursor wrap misbehaves
+ * then in full screen mode resulting in screen corruption.
+ */
+ if (-1 == x_pt.pt_codepage) {
+ x_pt.pt_codepage = GetConsoleOutputCP();
+ trace_log("\tcodepage: %d\n", x_pt.pt_codepage);
+ }
+ if (TA_CYGWIN & t_attributes) {
+ x_pt.pt_attributes |= TF_ACYGWIN; /* Cygwin terminal */
+ tf_xn = 1;
+ }
+#endif /*__CYGWIN__*/
+
+ if (tf_km) {
+ x_pt.pt_attributes |= TF_AMETAKEY;
+ }
+
+ if (0 == x_pt.pt_codepage) {
+ x_pt.pt_codepage = 437; /* default */
+ }
+}
+
+
+static int
+hasfeature(const char *term, const char *what)
+{
+ const char *p = strstr(term, what);
+
+ if (p > term) { /* -rv[-] */
+ const unsigned len = strlen(what);
+
+ if ('-' == p[-1] && ('-' == p[len] || 0 == p[len])) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+/* Function: ttdefaultscheme
+ * Retrieve the derived/guessed default background color based on the either
+ * the published terminal background or the terminal type.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * Name of default color scheme dark or light.
+ */
+const char *
+ttdefaultscheme(void)
+{
+ int isdark = 0;
+
+ if (x_pt.pt_schemedark >= 0) { /* explicit configuration */
+ isdark = x_pt.pt_schemedark;
+
+ } else if (0 == (TA_LIGHT & t_attributes)) {
+ if (tt_defaultbg != NOCOLOR) { /* 0-6 or 8 */
+ if (tt_defaultbg <= 6 || 8 == tt_defaultbg) {
+ isdark = 1;
+ }
+ } else { /* generally dark */
+ if (TA_DARK & t_attributes) {
+ isdark = 1;
+ }
+ }
+ }
+
+ x_pt.pt_schemedark = isdark;
+ trace_log("ttdefaultscheme=%s\n", (isdark ? "dark" : "light"));
+ return (isdark ? "dark" : "light");
+}
+
+
+/* Function: term_open
+ * Open the console.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_open(scrprofile_t *profile)
+{
+ io_device_add(TTY_INFD); /* stream registration */
+ sys_initialise();
+ term_identification(); /* terminal identification */
+ term_sizeget(&profile->sp_rows, &profile->sp_cols);
+ profile->sp_colors = tt_colors;
+}
+
+
+/* Function: term_close
+ * Close the console.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_close(void)
+{
+ term_tidy();
+ sys_shutdown();
+ tty_egaflag = -1;
+}
+
+
+/* Function: term_ready
+ * Run-time initialisation.
+ *
+ * Parameters:
+ * repaint - *true* if the screen should be repainted.
+ * profile - console profile.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_ready(int repaint, scrprofile_t *profile)
+{
+ static unsigned once;
+
+ trace_log("term_ready(%d)\n", repaint);
+
+ /*
+ * dump configuration
+ */
+ if (! once) {
+ const char *o_CS = tc_cs;
+
+ if (! xf_scrollregions) {
+ tc_cs = tc_cS = NULL; /* disable scrolling region */
+ }
+
+ if (! tc_ce) { /* erasing a line */
+ tty_tceeol = ttcols();
+ } else {
+ tty_tceeol = term_cost(tc_ce);
+ }
+
+ if (tc_cs && tc_sr) { /* inserting a line */
+ tty_tcinsl = term_cost(tc_cs) * 2 + term_cost(tc_sr);
+ } else if (tc_pAL) {
+ tty_tcinsl = term_cost(tc_pAL);
+ } else if (tc_al) {
+ tty_tcinsl = term_cost(tc_al);
+ } else {
+ tty_tcinsl = 0xffff;
+ }
+
+ if (tc_cs) { /* delete a line */
+ tty_tcdell = term_cost(tc_cs) * 2 + 1;
+ } else if (tc_pDL) {
+ tty_tcdell = term_cost(tc_pDL);
+ } else if (tc_dl) {
+ tty_tcdell = term_cost(tc_dl);
+ } else {
+ tty_tcdell = 0xffff;
+ }
+ /* we can ins/del lines */
+ t_insdel = (tc_al || tc_pAL) && (tc_dl || tc_pDL);
+ t_padchar = (tf_npc ? -1 : (tc_pc ? *tc_pc : 0));
+ t_acs_locale_breaks = acs_locale_breaks();
+
+ trace_log("TTY summary:\n");
+
+ if (-1 == t_padchar) {
+ trace_log("\tNo padding character\n");
+ } else {
+#if defined(HAVE_OSPEED)
+ trace_log("\tPadding character %d, at ospeed %d\n", t_padchar, ospeed);
+#else
+ trace_log("\tPadding character %d, at baud %d\n", t_padchar, baudrate());
+#endif
+ }
+
+ if (t_insdel) {
+ trace_log("\tInsert/delete scrolling available.\n");
+ }
+
+ if (o_CS) {
+ trace_log("\tScroll regions available.\n");
+ }
+
+ if (! xf_graph) {
+ trace_log("\tAlternative character support disabled.\n");
+ } else if (tc_acs_enable || x_pt.pt_graphics_mode[0]) {
+ trace_log("\tAlternative character support available.\n");
+ }
+ if (t_acs_locale_breaks) {
+ trace_log("\tlocale breaks alternative character support.\n");
+ }
+
+ if (xf_noinit) {
+ trace_log("\ttermcap init/reinit disabled.\n");
+ }
+
+ if (xf_nokeypad) {
+ trace_log("\ttermcap keypad init/reinit disabled.\n");
+ }
+
+ trace_log("\tDeleting lines using %s\n",
+ ((tc_cs) ? "scrolling regions" : t_insdel ? "line del/ins" : "hard refresh"));
+ trace_log("\tInserting lines using %s\n",
+ ((tc_cs && tc_sr) ? "scrolling regions" : t_insdel ? "line del/ins" : "hard refresh"));
+ trace_log("\t%-55s : %d\n", "Erase line cost", tty_tceeol);
+ trace_log("\t%-55s : %d\n", "Insert line cost", tty_tcinsl);
+ trace_log("\t%-55s : %d\n", "Delete line cost", tty_tcdell);
+ trace_log("\t%-55s : %d\n", "Colors", tt_colors);
+ trace_log("\t%-55s : %d\n", " Default fg", tt_defaultfg);
+ trace_log("\t%-55s : %d\n", " Default bg", tt_defaultbg);
+ ++once;
+ }
+
+ /*
+ * configure terminal
+ */
+ term_colorreset();
+
+ if (repaint) {
+ if (x_pt.pt_init[0]) /* terminal specific init */
+ ttputctl2(x_pt.pt_init, 0, 0);
+ xterm_colors(t_colorsuser);
+ if (! xf_noinit)
+ ttputpad(tc_ti); /* enable cup (cursor addressing) */
+ if (! xf_nokeypad)
+ ttputpad(tc_ks); /* put terminal in ``keypad-transmit'' */
+ if (xf_graph)
+ ttputpad(tc_acs_enable); /* enable alt character set */
+ ttputpad(tc_vs ? tc_vs : tc_ve); /* enable enhanced cursor */
+ if (tf_am)
+ ttputpad(tc_am_on); /* enable automatic margins */
+ ttputpad(tc_mm); /* enable meta key-codes */
+ }
+
+ /*
+ * terminal specific specials
+ */
+ if (t_attributes & TA_CYGWIN) {
+ if (xf_cygwinkb) {
+ ttpush("\033[?2000h"); /* enable RAW mode (gives us WIN32 scancodes) */
+ }
+
+ } else if (t_attributes & TA_MINTTY) {
+ if (xf_mouse) { /* mouse enabled? */
+ ttpush("\033[?7786h"); /* mouse-wheel reports only */
+ }
+
+ } else if (t_attributes & TA_VT100LIKE) {
+ ttpush("\033=\033[?1]"); /* enable cursor keys */
+ }
+
+ if (profile) {
+ profile->sp_lastsafe = term_lastsafe();
+ profile->sp_colors = tt_colors;
+ }
+
+ tt_style = 0;
+ tt_cursor = 1;
+ tt_active = 1;
+ term_flush();
+}
+
+
+/* Function: term_feature
+ * Signal a terminal feature change.
+ *
+ * Parameters:
+ * ident - Feature identifier.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_feature(int ident, scrprofile_t *profile)
+{
+ trace_log("term_feature(%d)\n", ident);
+
+ switch (ident) {
+ case TF_INIT:
+ if (tty_open && x_pt.pt_init[0]) {
+ ttputctl2(x_pt.pt_init, 0, 0);
+ }
+ break;
+
+ case TF_COLORDEPTH:
+ case TF_DEFAULT_FG:
+ case TF_DEFAULT_BG:
+ case TF_XTERM_PALETTE:
+ if (tty_open) {
+ term_colors();
+ profile->sp_colors = tt_colors;
+ }
+ break;
+
+ case TF_COLORMAP: /* terminal color palette */
+ if (x_pt.pt_colormap[0]) {
+ strxcpy(t_colorsuser, x_pt.pt_colormap, sizeof(t_colorsuser));
+ if (tty_open) {
+ xterm_colors(t_colorsuser);
+ }
+ }
+ break;
+
+ case TF_COLORPALETTE: { /* user defined palette */
+ const char *cursor = x_pt.pt_colorpalette;
+ unsigned col = 0;
+
+ for (col = 0; col < (sizeof(tt_colormap)/sizeof(tt_colormap[0])); ++col) {
+ if (cursor && *cursor) {
+ if (isdigit(*cursor)) {
+ int val;
+
+ if ((val = atoi(cursor)) >= 0) {
+ tt_colormap[col] = val;
+ }
+ }
+ if (NULL != (cursor = strchr(cursor, ','))) {
+ ++cursor;
+ }
+ }
+ }
+ x_pt.pt_xtpalette = -2;
+ }
+ break;
+
+ case TF_ENCODING:
+ break;
+ case TF_UNICODE_VERSION:
+ if (x_pt.pt_unicode_version[0]) {
+ ucs_width_set(x_pt.pt_unicode_version);
+ }
+ break;
+ }
+}
+
+
+/* Function: term_display
+ * Invoked upon the display being enabled.
+ *
+ * This interface is hooked into the display_windows() primitive which (by default) is
+ * post execution of any terminal specific macros, for example
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_display(void)
+{
+ trace_log("term_display()\n");
+
+ if (term_isutf8()) { /* auto-detect UTF8 term support */
+ x_pt.pt_attributes |= TF_AUTF8ENCODING; /* publish UTF8 */
+ if (0 == x_pt.pt_encoding[0]) {
+ strcpy(x_pt.pt_encoding, "UTF-8");
+ }
+ if (xf_disptype < 0) {
+ xf_disptype = DISPTYPE_UTF8;
+ }
+ x_display_ctrl |= DC_UNICODE;
+
+ } else {
+ if (xf_disptype < 0) { /* default disp-type */
+ if (vtis8bit()) {
+ if (0 == x_pt.pt_encoding[0]) {
+ strcpy(x_pt.pt_encoding, "latin1");
+ }
+ xf_disptype = DISPTYPE_8BIT;
+ } else {
+ if (0 == x_pt.pt_encoding[0]) {
+ strcpy(x_pt.pt_encoding, "us-ascii");
+ }
+ xf_disptype = DISPTYPE_7BIT;
+ }
+ }
+ }
+
+ if (! xf_graph) { /* no graphic */
+ ttboxcharacters(TRUE);
+ }
+}
+
+
+static int
+term_control(int action, int param, ...)
+{
+ switch (action) {
+ case SCR_CTRL_NORMAL: /* normal color */
+ if (tty_open) {
+ term_colorreset();
+ }
+ break;
+
+ case SCR_CTRL_SAVE:
+ if (tty_open) {
+ ttmove(ttrows()-1, 0);
+ if (param) {
+ term_tidy();
+ } else {
+ term_colorreset();
+ term_styleoff();
+ tteeol();
+ }
+ }
+ break;
+
+ case SCR_CTRL_RESTORE:
+ if (! tty_open) {
+ ttopen();
+ }
+ term_ready(TRUE, NULL);
+ break;
+
+ case SCR_CTRL_COLORS: /* color change */
+ break;
+
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+
+/* Function: ttisetup
+ * TERMINFO/TERMCAP setup.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * Terminal name on success, otherwise the interface exits.
+ */
+static const char *
+ttisetup(void)
+{
+ const char *term;
+
+ if (NULL == (term = ggetenv("TERM"))) {
+ fprintf(stderr, "Environment variable TERM not defined!\n");
+ exit(1);
+ }
+
+#if defined(HAVE_TERMINFO)
+ XF_TERMINFO {
+ trace_log("TERMINFO(%s) open\n", term);
+ if (setupterm((char *)term, fileno(stdout), NULL) != 0) {
+ fprintf(stderr, "Terminal type '%s' not found in terminfo database.\n", term);
+ exit(1);
+ }
+ }
+#endif
+#if defined(HAVE_TERMCAP)
+ XF_TERMCAP {
+ tcapcursor = tcapstrings;
+ memset(tcapstrings, 0, sizeof(tcapstrings));
+
+ trace_log("TERMCAP(%s) open\n", term);
+ if (tgetent(tcapbuffer, (char *)term) != 1) {
+ fprintf(stderr, "Terminal type '%s' not found in termcap.\n", term);
+ exit(1);
+ }
+ }
+#endif
+
+ return term;
+}
+
+
+/* Function: ttiname
+ * Retrieve the attribute name.
+ *
+ * Parameters:
+ * ti - Attribute specification.
+ *
+ * Returns:
+ * Attribute name.
+ */
+static const char *
+ttiname(const Term_t *ti)
+{
+ const char *name = NULL;
+
+#if defined(HAVE_TERMINFO)
+ XF_TERMINFO name = ti->terminfoname;
+#endif
+#if defined(HAVE_TERMCAP)
+ XF_TERMCAP name = ti->termcapname;
+#endif
+ return name;
+}
+
+
+/* Function: ttigetstr
+ * t[i]getstr() interface.
+ *
+ * Parameters:
+ * ti - Attribute specification.
+ *
+ * Returns:
+ * Sequence buffer address, otherwis NULL.
+ */
+static const char *
+ttigetstr(const Term_t *ti)
+{
+ char *s = NULL;
+
+#if defined(HAVE_TERMINFO)
+ XF_TERMINFO {
+ const char *name = ti->terminfoname;
+
+ s = tigetstr((char *) name);
+ if ((char *)-1 == s) { /* 'name' is not a string capability */
+ trace_log("\ttgetstr(%s) = unknown\n", name);
+ s = NULL;
+ }
+ }
+#endif
+#if defined(HAVE_TERMCAP)
+ XF_TERMCAP {
+ /*
+ * Under normal conditions tgetstr() should perform as descripted but doesn't on
+ * all systems so workout known issues.
+ *
+ * "The tgetstr routine returns the string entry for id, or zero if it is not
+ * available. Use tputs to output the returned string. The return value will also
+ * be copied to the buffer pointed to by area, and the area value will be updated
+ * to point past the null ending this value."
+ *
+ * Note, only seen under an older curses implementation.
+ */
+ const char *name = ti->termcapname;
+ char *ocursor = tcapcursor; /* current storage addr */
+
+ if (NULL != (s = tgetstr((char *) name, &tcapcursor)) && *s) {
+ const int slen = strlen(s);
+
+ if (ocursor == tcapcursor) { /* broken tgetstr() */
+ strcpy(ocursor, s);
+ tcapcursor = ocursor + slen + 1;
+ }
+ s = ocursor; /* lookup result */
+ if (tcapcursor >= tcapstrings + TC_SLEN) {
+ fprintf(stderr, "Terminal description too large (>%dk)\n", (TC_SLEN/1024) + 1);
+ exit(1);
+ }
+ assert(tcapcursor == ocursor + slen + 1);
+ } else {
+ s = NULL; /* not found, zero length */
+ }
+ }
+#endif
+ return s;
+}
+
+
+/* Function: ttigetnum
+ * t[i]getnum() interface.
+ *
+ * Parameters:
+ * ti - Attribute specification.
+ *
+ * Returns:
+ * Attribute value, otherwise -1.
+ */
+static int
+ttigetnum(const Term_t *ti)
+{
+ const char *name = "n/a";
+ int num = -1;
+
+#if defined(HAVE_TERMINFO)
+ XF_TERMINFO {
+ name = ti->terminfoname;
+ num = tigetnum((char *) name);
+ }
+#endif
+#if defined(HAVE_TERMCAP)
+ XF_TERMCAP {
+ name = ti->termcapname;
+ num = tgetnum((char *) name);
+ }
+#endif
+ if (num < -1) {
+ trace_log("\ttgetnum(%s) = error (%d)\n", name, num);
+ }
+ return (num >= -1 ? num : -1); /* -1 or greater */
+}
+
+
+/* Function: ttigetflag
+ * t[i]getflag() interface.
+ *
+ * Parameters:
+ * ti - Attribute specification.
+ *
+ * Returns:
+ * Attribute value of either 0 or 1.
+ */
+static int
+ttigetflag(const Term_t *ti)
+{
+ const char *name = "n/a";
+ int flag = -1;
+
+#if defined(HAVE_TERMINFO)
+ XF_TERMINFO {
+ name = ti->terminfoname;
+ flag = tigetflag((char *) name);
+ }
+#endif
+#if defined(HAVE_TERMCAP)
+ XF_TERMCAP {
+ name = ti->termcapname;
+ flag = tgetflag((char *) name);
+ }
+#endif
+ if (flag < 0) {
+ trace_log("\ttgetflag(%s) = error (%d)\n", name, flag);
+ }
+ return (flag >= 0 ? flag : 0); /* 0 or 1 */
+}
+
+
+int
+ttisetstr(const char *tag, int taglen, const char *value)
+{
+ __CUNUSED(tag) __CUNUSED(taglen) __CUNUSED(value)
+ return -1;
+}
+
+
+int
+ttisetnum(const char *tag, int taglen, const char *value)
+{
+ __CUNUSED(tag) __CUNUSED(taglen) __CUNUSED(value)
+ return -1;
+}
+
+
+int
+ttisetflag(const char *tag, int taglen, const char *value)
+{
+ __CUNUSED(tag) __CUNUSED(taglen) __CUNUSED(value)
+ return -1;
+}
+
+
+/* Function: acs_dump
+ * Alternative character dump.
+ *
+ * Parameters:
+ * bp - Buffer object address.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+acs_dump(const char *bp)
+{
+ const unsigned char *p = (unsigned char *)bp;
+ unsigned char ident, ch;
+ unsigned i;
+
+ while (*p) {
+ const char *desc = "unknown";
+
+ ident = *p++;
+ if (! isprint(ident)) {
+ continue; /* unsure, yet needed for rxvt-cygwin */
+ }
+ ch = *p++;
+
+ for (i = 0; i < (sizeof(term_characters)/sizeof(term_characters[0])); ++i)
+ if (term_characters[i].ident == ident) {
+ desc = term_characters[i].name;
+ break;
+ }
+
+ trace_log("\t\t%-30s %c/0x%x : %u/0x%x\n", desc, ident, ident, ch, ch);
+ }
+}
+
+
+/* Function: acs_boxcharacters
+ * Alternative character box character import.
+ *
+ * Parameters:
+ * bx - Box character spec.
+ *
+ * Returns:
+ * Converted box characters into an acs specification.
+ */
+static const char *
+acs_box_characters(const char *bx)
+{
+ char acs[32], *t_acs = acs;
+
+#define acs_push_bx(_i, _c) *t_acs++ = _i, *t_acs++ = _c
+
+ acs_push_bx(TACS_ULCORNER, bx[0]); /* 'l' */
+ acs_push_bx(TACS_HLINE, bx[1]); /* 'q' */
+ acs_push_bx(TACS_URCORNER, bx[2]); /* 'k' */
+ acs_push_bx(TACS_VLINE, bx[3]); /* 'x' */
+ acs_push_bx(TACS_LRCORNER, bx[4]); /* 'j' */
+ acs_push_bx(TACS_LLCORNER, bx[5]); /* 'm' */
+ acs_push_bx(TACS_TTEE, bx[6]); /* 'w' */
+ acs_push_bx(TACS_RTEE, bx[7]); /* 'u' */
+ acs_push_bx(TACS_BTEE, bx[8]); /* 'v' */
+ acs_push_bx(TACS_LTEE, bx[9]); /* 't' */
+ acs_push_bx(TACS_PLUS, bx[10]); /* 'n' */
+
+#undef acs_push_bx
+ *t_acs = 0;
+
+ return chk_salloc(acs);
+}
+
+
+/* Function: acs_locale_breaks
+ * Check for known cases where a UTF-8 locale breaks the alternate character set.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * TRUE or FALSE.
+ */
+static int
+acs_locale_breaks(void)
+{
+ const char *env;
+
+ if ((env = ggetenv("NCURSES_NO_UTF8_ACS")) != 0) {
+ return atoi(env); /* ncurses compatibility */
+
+ } else if ((env = ggetenv("TERM")) != 0) {
+ if (strstr(env, "linux")) {
+ return TRUE;
+ }
+
+ if (strstr(env, "screen") &&
+ ((env = ggetenv("TERMCAP")) != 0 && strstr(env, "screen") != 0) &&
+ strstr(env, "hhII00") != 0) {
+
+#define IS_CTRLN(s) ((s) != 0 && strstr(s, "\016") != 0)
+#define IS_CTRLO(s) ((s) != 0 && strstr(s, "\017") != 0)
+
+ if (IS_CTRLN(tc_acs_start) || IS_CTRLO(tc_acs_start) ||
+ IS_CTRLN(set_attributes) || IS_CTRLO(set_attributes)) {
+ return TRUE;
+ }
+
+#undef IS_CTRLN
+#undef IS_CTRLO
+ }
+ }
+ return FALSE;
+}
+
+
+/* Function: term_xtermlike
+ * Determine the current terminal is an xterm style.
+ *
+ * Parameters:
+ * term - Terminate name.
+ *
+ * Returns:
+ * nothing.
+ */
+static int
+term_xtermlike(const char *term)
+{
+ static const struct {
+ const char *desc;
+ unsigned len;
+ } xtermlike[] = {
+#define XTERMLIKE(x) { x, sizeof(x)-1 }
+ XTERMLIKE("xterm"), /* generic */
+ XTERMLIKE("aixterm"), /* AIX */
+ XTERMLIKE("mintty"), /* non-standard. normally "xterm-256color" */
+ XTERMLIKE("rxvt"),
+ XTERMLIKE("urxvt"), /* Unicode rxvt */
+ XTERMLIKE("Eterm"),
+ XTERMLIKE("gnome"), /* gnome-terminal */
+ XTERMLIKE("dtterm"), /* CDE terminal */
+ XTERMLIKE("cygwin") /* Cygwin console */
+ };
+#undef XTERMLIKE
+ int ret = 0;
+
+ if (term) {
+ unsigned i;
+
+ if (x_pt.pt_xtcompat >= 0) {
+ ret = x_pt.pt_xtcompat; /* feature override */
+ } else {
+ for (i = 0; i < (unsigned)(sizeof(xtermlike)/sizeof(xtermlike[0])); ++i)
+ if (0 == strncmp(term, xtermlike[i].desc, xtermlike[i].len) &&
+ ('\0' == term[xtermlike[i].len] || '-' == term[xtermlike[i].len])) {
+ /*
+ * for example,
+ * xterm-color
+ */
+ ret = 1;
+ break;
+ }
+ }
+ }
+ trace_log("\txtermlike(%s) : %d\n", (term ? term : ""), ret);
+ x_pt.pt_xtcompat = ret;
+ return ret;
+}
+
+
+/* Function: ttkeys
+ * Map keys from termcap database to our keys. These are often overridden by the term
+ * macros, but at least we can set up some sensible default that are likely to work.
+ *
+ * Parameters:
+ * repaint - *true* if the screen should be repainted.
+ *
+ * Returns:
+ * nothing.
+ */
+void
+ttkeys(void)
+{
+ unsigned i;
+
+ trace_log("ttkeys()\n");
+
+ /*
+ * Keys
+ */
+ for (i = 0; i < (sizeof(term_keys)/sizeof(term_keys[0])); ++i)
+ if (term_keys[i].value.i_str && term_keys[i].token) {
+ key_define_key_seq((int)term_keys[i].token, term_keys[i].value.i_str);
+ }
+
+ /*
+ * Color
+ */
+ if (tf_Colors > 2 /*user specification*/ ||
+ (tc_Color_Fg && tc_Color_Bg) || (tc_ANSI_Color_Fg && tc_ANSI_Color_Bg) ||
+ ggetenv("COLORTERM") /*override*/) {
+ x_pt.pt_color = TRUE;
+ }
+
+ term_colors();
+
+ /*
+ * Graphic (alt) characters
+ */
+ for (i = 0; i < sizeof(tc_acs_map); ++i) { /* one-to-one */
+ tc_acs_map[i] = (unsigned char)(i < 32 ? ' ' : i);
+ }
+
+ if (tc_acs_start && xf_graph /*-1 or 1*/) {
+ const char *p;
+
+ if (NULL == (p = tc_graphic_pairs)) { /* build character map */
+ p = tc_graphic_default;
+ }
+
+ while (*p) {
+ i = *p++;
+ if (! isprint(i)) {
+ continue; /* unsure, yet needed for rxvt-cygwin */
+ }
+ tc_acs_map[i & 0x7f] = *p++;
+ }
+
+ x_pt.pt_tty_graphicsbox = TRUE;
+ x_pt.pt_top_left[0] = tc_acs_map[TACS_ULCORNER];
+ x_pt.pt_top_right[0] = tc_acs_map[TACS_URCORNER];
+ x_pt.pt_bot_left[0] = tc_acs_map[TACS_LLCORNER];
+ x_pt.pt_bot_right[0] = tc_acs_map[TACS_LRCORNER];
+ x_pt.pt_vertical[0] = tc_acs_map[TACS_VLINE];
+ x_pt.pt_horizontal[0] = tc_acs_map[TACS_HLINE];
+ x_pt.pt_top_join[0] = tc_acs_map[TACS_TTEE];
+ x_pt.pt_bot_join[0] = tc_acs_map[TACS_BTEE];
+ x_pt.pt_cross[0] = tc_acs_map[TACS_PLUS];
+ x_pt.pt_left_join[0] = tc_acs_map[TACS_RTEE];
+ x_pt.pt_right_join[0] = tc_acs_map[TACS_LTEE];
+
+ trace_ilog("ACS mapping\n");
+ trace_ilog(" top %d/0x%x\n", x_pt.pt_top_right[0], x_pt.pt_top_right[0]);
+ trace_ilog(" bot %d/0x%x\n", x_pt.pt_bot_left[0], x_pt.pt_bot_left[0]);
+ trace_ilog(" bot %d/0x%x\n", x_pt.pt_bot_right[0], x_pt.pt_bot_right[0]);
+ trace_ilog(" verti %d/0x%x\n", x_pt.pt_vertical[0], x_pt.pt_vertical[0]);
+ trace_ilog(" horiz %d/0x%x\n", x_pt.pt_horizontal[0], x_pt.pt_horizontal[0]);
+ trace_ilog(" top %d/0x%x\n", x_pt.pt_top_join[0], x_pt.pt_top_join[0]);
+ trace_ilog(" bot %d/0x%x\n", x_pt.pt_bot_join[0], x_pt.pt_bot_join[0]);
+ trace_ilog(" cross %d/0x%x\n", x_pt.pt_cross[0], x_pt.pt_cross[0]);
+ trace_ilog(" left %d/0x%x\n", x_pt.pt_left_join[0], x_pt.pt_left_join[0]);
+ trace_ilog(" right %d/0x%x\n", x_pt.pt_right_join[0], x_pt.pt_right_join[0]);
+ }
+}
+
+
+/* Function: term_colors
+ * Load the given color specification.
+ *
+ * Parameters:
+ * value - Color scheme.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_colors(void)
+{ /* save user color specification */
+ int col, source = 0;
+
+ /* configure color depth */
+ if (xf_color > 1) {
+ tt_colors = xf_color; /* command line override */
+ source = 2;
+
+ } else if (TA_MONO & t_attributes) {
+ tt_colors = 2; /* mono feature (xterm-mono) */
+ source = 3;
+
+ } else if (x_pt.pt_colordepth > 1) {
+ tt_colors = x_pt.pt_colordepth; /* set_term_feature() */
+ source = 1;
+
+ } else if (x_pt.pt_color /*-1 or 1*/) {
+ if (t_attributes & TA_XTERMLIKE) {
+ tt_colors = ANSI_COLORS;
+
+ } else if (0 == (tt_colors = tf_Colors)) {
+ if (tc_ANSI_Color_Fg && tc_ANSI_Color_Bg) {
+ tt_colors = 16;
+ } else if (tc_Color_Fg && tc_Color_Bg) {
+ tt_colors = 8;
+ } else {
+ tt_colors = 0;
+ }
+ }
+ }
+
+ /* configure colors */
+ assert((COLOR_NONE + 1) == (sizeof(tt_colormap)/sizeof(tt_colormap[0])));
+ assert((COLOR_NONE + 1) == (sizeof(color_map)/sizeof(color_map[0])));
+
+ trace_ilog("ttcolormap:\n");
+ for (col = 0; col <= COLOR_NONE; ++col) {
+ int color = -1;
+
+ if (-2 == x_pt.pt_xtpalette) { /* user defined palette */
+ if ((color = tt_colormap[col]) <= 0) {
+ color = -1;
+ }
+ }
+
+ if (color < 0) {
+ if (tt_colors >= 256) {
+ if (0 == x_pt.pt_xtpalette) { /* compat-16 mode */
+ color = color_map[col].c256_compat;
+ } else {
+ color = color_map[col].c256;
+ }
+
+ } else if (tt_colors >= 88) {
+ if (0 == x_pt.pt_xtpalette) { /* compat-16 mode */
+ color = color_map[col].c88_compat;
+ } else {
+ color = color_map[col].c88;
+ }
+
+ } else if (tt_colors >= 16) {
+ color = color_map[col].c16;
+
+ } else {
+ color = color_map[col].c8;
+ }
+ }
+
+ tt_colormap[col] = color;
+ trace_ilog("\t%16s [%2d] = %d\n", color_name(col, "unknown"), col, tt_colormap[col]);
+ assert(color_map[col].ident == col);
+ }
+
+ trace_ilog("term_colors(source=%d,depth=%d)\n", source, tt_colors);
+ x_pt.pt_colordepth = tt_colors; /* derived depth */
+
+ if (tt_colors > 2) {
+ x_display_ctrl |= DC_SHADOW_SHOWTHRU;
+ }
+ term_fgbg();
+}
+
+
+/* Function: term_fgbg
+ * Load the environment settings (if any) which define the default colors configurations.
+ *
+ * The supported configurations are NCURSES_ASSUMED_COLORS, COLORFGBG (rxvt/mrxvt)
+ * and DEFAULT_COLORS.
+ *
+ * The following are examples of their settings;
+ *
+ * NCURSES_ASSUMED_COLORS='0;15'
+ *
+ * COLORFGBG='0;default;15'
+ *
+ * DEFAULT_COLORS='0;15'
+ *
+ * Notes:
+ * The format of the COLORFGBG variable is not documented as such and there two
+ * known formats. The two formats correspond to whether the xpm library is used or
+ * not.
+ *
+ * If rxvt is compiled with xpm support, the variable has three fields. In either
+ * case, the background color is the last field.
+ *
+ * Parameters:
+ * src - Buffer cursor.
+ * result - Storage for decoded result.
+ *
+ * Returns:
+ * Final cursor position.
+ */
+static void
+term_fgbg(void)
+{
+ const char *env;
+
+ tt_defaultfg = tt_defaultbg = NOCOLOR; /* unknown */
+
+ if (NULL != (env = ggetenv("NCURSES_ASSUMED_COLORS"))) {
+ int count, fg = NOCOLOR, bg = NOCOLOR;
+ char sep;
+
+ if ((count = sscanf(env, "%d%c%d%c", &fg, &sep, &bg, &sep)) >= 1) {
+ if (fg >= 0 && fg <= 255) tt_defaultfg = fg;
+ if (count >= 3) {
+ if (bg >= 0 && bg <= 255) tt_defaultbg = bg;
+ }
+ }
+
+ } else {
+ if (NULL != (env = ggetenv("COLORFGBG")) ||
+ NULL != (env = ggetenv("DEFAULT_COLORS"))) {
+ env = fgbg_value(env, &tt_defaultfg);
+ env = fgbg_value(env, &tt_defaultbg);
+ if (*env) { /* XPM support, last field is background */
+ fgbg_value(env, &tt_defaultbg);
+ }
+ }
+ }
+ /* apply color */
+ tt_defaultfg = fgbg_import(tt_defaultfg, x_pt.pt_defaultfg);
+ tt_defaultbg = fgbg_import(tt_defaultbg, x_pt.pt_defaultbg);
+}
+
+
+/* Function: fgbg_value
+ * Decode a COLORFGBG or DEFAULT_COLORS color specification.
+ *
+ * Parameters:
+ * src - Buffer cursor.
+ * result - Storage for decoded result.
+ *
+ * Returns:
+ * Final cursor position.
+ */
+static const char *
+fgbg_value(const char *src, int *result)
+{
+ const char *end = NULL;
+
+ if (0 == strncmp(src, "default", 7)) {
+ end = src + 7; /* special case */
+ } else {
+ char *endp = 0;
+ int value = (int) strtol(src, &endp, 0);
+
+ if (0 == endp) {
+ end = src;
+ } else if (value >= 0 && value <= 255) {
+ *result = (unsigned) value;
+ end = endp;
+ }
+ while (*end && *end != ';') {
+ ++end;
+ }
+ }
+
+ if (*end == ';') {
+ ++end;
+ }
+ return end;
+}
+
+
+static unsigned
+fgbg_import(unsigned edefault, int udefault)
+{
+ if (NOCOLOR == edefault) {
+ if (udefault >= 0) {
+ return udefault;
+ }
+ return NOCOLOR;
+ }
+ if (edefault < ANSI_COLORS) {
+ return ansicolor_map[ edefault ];
+ }
+ return edefault;
+}
+
+
+/* Function: xterm_colors
+ * Manage the xterm color pairs
+ *
+ * Parameters:
+ * value - Specification.
+ *
+ * Notes:
+ * ESC]4; c; spec ?
+ *
+ * Change Color Number c to the color specified by spec, i.e., a name or RGB
+ * specification as per XParseColor. Any number of c name pairs may be given.
+ *
+ * The color numbers correspond to the ANSI colors 0-7, their bright versions 8-15,
+ * and if supported, the remainder of the 88-color or 256-color table. Each successive
+ * parameter changes the next color in the list. The value of Ps tells the starting
+ * point in the list. The colors are specified by name or RGB specification as per
+ * XParseColor.
+ *
+ * If a "?" is given rather than a name or RGB specification, xterm replies with a
+ * control sequence of the same form which can be used to set the corresponding color.
+ * Because more than one pair of color number and specification can be given in one
+ * control sequence, xterm can make more than one reply.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+xterm_colors(const char *value)
+{
+ if (0 == (t_attributes & TA_XTERMLIKE)) /* xterm specific */
+ return;
+
+ if (NULL == value || 0 == value[0])
+ return;
+
+ trace_ilog("xterm_colors(%s)\n", value);
+
+ if (value != t_colorsorg) {
+ if (0 == t_colorsorg[0]) { /* retrieve and save existing */
+ xterm_colors_get(t_colorsorg, sizeof(t_colorsorg));
+ }
+ }
+
+ if (0 != t_colorsorg[0]) { /* set new value (if save was possible) */
+ xterm_colors_set(value);
+ }
+}
+
+
+static int
+xterm_colors_get(char *buffer, int length)
+{
+ int color, len;
+
+ if (0 == (t_attributes & TA_XTERM)) { /* xterm specific */
+ return -1;
+ }
+
+ term_flush(); /* clear existing obuf */
+
+ for (len = 0, color = 0; color < XTERM_COLORS; ++color) {
+ /*
+ * foreach(color)
+ */
+ int cnt = sprintf((char *)t_buffer, "\033]4;%d;?\007", color);
+
+ if (cnt != sys_write(1, t_buffer, cnt) ||
+ (cnt = term_read((char *)t_buffer, sizeof(t_buffer), 5 * 1000)) <= 0 ||
+ sscanf((char *)t_buffer, "%*[^;];%*[^;];%s", buffer + len + (len ? 1 : 0)) != 1) {
+ /*
+ * Note, 'rxvt' and the 'linux console' only support set.
+ *
+ * rxvt shall report (on stderr)/
+ * rxvt: can't determine colour: ?
+ */
+ trace_ilog("\terr[%d] (%*s)\n", color, cnt, t_buffer);
+ break;
+ }
+
+ trace_ilog("\tget[%d]=%s\n", color, buffer + len + (len ? 1 : 0));
+
+ if (len) {
+ buffer[len] = ','; /* separator */
+ }
+ len += strlen(buffer + len);
+ assert(len < length-1);
+
+ if ('\007' == buffer[len-1]) { /* strip terminator */
+ buffer[len-1] = '\0', --len;
+ }
+ }
+ return 0;
+}
+
+
+static int
+xterm_colors_set(const char *value)
+{
+ const char *term;
+ int color, len, cnt;
+
+ if (0 == (t_attributes & TA_XTERMLIKE)) { /* xterm specific */
+ return -1;
+ }
+
+ term_flush(); /* clear existing obuf */
+
+ cnt = sprintf((char *)t_buffer, "\033]4"); /* dynamic color command */
+
+ for (color = 0; color < XTERM_COLORS; ++color) {
+
+ if ((const char *)NULL == (term = strchr(value, ','))) {
+ len = strlen(value);
+ } else {
+ len = term - value;
+ }
+
+ trace_ilog("\tset[%d]=%.*s\n", color, len, value );
+ if (len) {
+ cnt += sprintf((char *)(t_buffer + cnt), ";%d;%.*s", color, len, value);
+ }
+
+ assert(cnt < (int)sizeof(t_buffer));
+ if (NULL == term) {
+ break;
+ }
+
+ value = term + 1; /* next field */
+ }
+
+ cnt += sprintf((char *)(t_buffer + cnt), "\007");
+ sys_write(1, t_buffer, cnt); /* terminator */
+ return 0;
+}
+
+
+/* Function: term_identification
+ * Request the terminal (VT100 and xterm style) to echo the "Device Attributes"
+ * report containing terminal type and version.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * Length of the buffer retrieved.
+ */
+static int
+term_identification(void)
+{
+#define XTERM_DEVICE_ATTR (sizeof(xterm_device_attr)-1)
+ static char xterm_device_attr[] = "\033[>c";
+ int ret = -1;
+
+#if defined(__CYGWIN__)
+ if (TA_CYGWIN & t_attributes) {
+ /*
+ * CYGWIN
+ */
+ struct utsname u = {0};
+ int r1 = 0, r2 = 0;
+
+ ret = -3;
+ if (uname(&u) >= 0) {
+ if (2 == sscanf(u.release, "%d.%d", &r1, &r2)) {
+ x_pt.pt_vtdatype = -3; /* source: xterm_cygwin */
+ x_pt.pt_vtdaversion = (r1 * 100) + (r2 > 99 ? 99 : r2);
+ }
+ trace_ilog("\tcygwin_uname(%s) = %d.%d\n", u.release, r1, r2);
+ }
+ return ret;
+ }
+#endif /*__CYGWIN__*/
+
+ if ((TA_VT100LIKE|TA_XTERM|TA_XTERMLIKE) & t_attributes) {
+ /*
+ * xterm and compatible terminals
+ */
+ const char *vstring;
+
+ /*
+ * XTERM_VERSION/
+ * Xterm(256) ==> 256
+ */
+ if (NULL != (vstring = ggetenv("XTERM_VERSION"))) {
+ char vname[32] = {0};
+ int vnumber = 0;
+ /* decode and return patch/version number */
+ if (2 == sscanf(vstring, "%32[^(](%u)", vname, &vnumber))
+ if (vnumber > 0) {
+ x_pt.pt_vtdatype = -2; /* source: xterm_version */
+ x_pt.pt_vtdaversion = vnumber;
+ ret = 0;
+ }
+ trace_ilog("XTERM_VERSION(%s) = %d (%s)\n", vstring, vnumber, vname);
+ }
+
+ /*
+ * device attribute
+ */
+ if (-1 == ret) {
+ char buffer[32] = {0};
+ int len = 0;
+
+ term_flush();
+ if (XTERM_DEVICE_ATTR == sys_write(1, xterm_device_attr, XTERM_DEVICE_ATTR) &&
+ (len = term_read(buffer, sizeof(buffer), -2)) > 1) {
+ /*
+ * Example/
+ * \033[>82;20710;0c
+ * ^type
+ * ^version
+ *
+ * Known terminal types/
+ * xterm (0) 0;256;0c
+ * mintty (77) 77;10003;0c
+ * screen (83)
+ * old rxvt (82)
+ * rxvt unicode (85)
+ */
+ trace_ilog("device_attr(%d, %s)\n", len, buffer);
+
+ if ('\033' == buffer[0] && '[' == buffer[1] &&
+ ('>' == buffer[2] || '?' == buffer[2])) {
+ int datype, daversion;
+
+ if (2 == sscanf(buffer + 3, "%d;%d", &datype, &daversion)) {
+ trace_ilog("==> type:%d, version:%d\n", datype, daversion);
+ x_pt.pt_vtdatype = datype;
+ x_pt.pt_vtdaversion = daversion;
+ if (77 == datype) {
+ t_attributes |= TA_MINTTY;
+ ++tf_xn;
+ }
+ ret = 0;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+/* Function: term_isutf8
+ * Determine whether the terminal supports UTF8 character encoding.
+ *
+ * Where possible limit terminal interaction, as such test *all*
+ * configuration/environment setting prior.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * *true* if UTF8, otherwise *false*.
+ */
+static int
+term_isutf8(void)
+{
+ int ret = 0;
+
+ if (DISPTYPE_UTF8 == xf_disptype) { /* explicitly enabled -- command line */
+ ret = 1;
+
+ } else if (DISPTYPE_7BIT == xf_disptype || DISPTYPE_8BIT == xf_disptype) {
+ ret = 0; /* explicitly disabled -- command line */
+
+ } else if (TA_LINUX & t_attributes) { /* linux console, not supported */
+ ret = -2;
+
+ } else if (TA_CYGWIN & t_attributes) { /* cygwin version (1.7+) */
+ if (-3 == x_pt.pt_vtdatype) {
+ const int r1 = x_pt.pt_vtdaversion / 100;
+ const int r2 = x_pt.pt_vtdaversion % 100;
+
+ if (2 <= r1 || (1 == r1 && 7 <= r2)) {
+ ret = 3;
+ }
+ }
+
+ } else if (x_pt.pt_encoding[0]) { /* terminal encoding/locale */
+ ret = (mchar_locale_utf8(x_pt.pt_encoding) ? 2 : -1);
+
+ } else if (sys_unicode_locale(TRUE)) { /* BTERM_LOCAL or LOCALE */
+ ret = 4;
+
+ } else if (TA_XTERM & t_attributes) {
+ /*
+ * Write a single utf8 character and check resulting cursor position.
+ *
+ * Source: ICU27 and general discussions
+ */
+#define XTERM_UTF8_TEST1 (sizeof(xterm_utf8_test1)-1)
+#define XTERM_UTF8_CLEAN1 (sizeof(xterm_utf8_clean1)-1)
+
+ static unsigned char xterm_utf8_test1[] = "\r" "\xc3\xb6" "\033[6n";
+ static unsigned char xterm_utf8_clean1[] = "\r \r";
+
+ ret = -5;
+ term_flush();
+ if (XTERM_UTF8_TEST1 == sys_write(1, (void *)xterm_utf8_test1, XTERM_UTF8_TEST1)) {
+ int row = -1, col = -1;
+ char buffer[32] = {0};
+ int len;
+
+ if ((len = term_read(buffer, sizeof(buffer), -2)) >= 4 &&
+ 2 == sscanf(buffer, "\033[%d;%dR", &row, &col)) {
+ if (2 == col) {
+ ret = 5; /* cursor in second column */
+ }
+ }
+ trace_ilog("\tisutf8A(%d) = col:%d\n", len, col);
+ sys_write(1, (void *)xterm_utf8_clean1, XTERM_UTF8_CLEAN1);
+ }
+
+ }
+
+ trace_ilog("UTF8 support=%d\n", ret);
+ return (ret >= 1 ? 1 : 0);
+}
+
+
+#if (XXX_MCHAR_DETECT)
+static void
+term_utf8_features(void)
+{
+#define XTERM_UTF8_TEST2 (sizeof(xterm_utf8_test2)-1)
+
+ static unsigned char xterm_utf8_test2[] = {
+ '\r', /* UTF* features */
+ 0xa5,
+ 0xc3, 0x84, 0xd9,
+ 0xa7,
+ 0xd8, 0xb8, 0xe0, 0xe0,
+ 0xa9,
+ 0xa9,
+ 0xb8, 0x88, 0xe5, 0xe5, 0x88,
+ 0xa2, 0xa2,
+ 0x1b, '[', '6', 'n', /* cursor position */
+ 0x00 /* NUL */
+ };
+
+ term_flush();
+
+ if (XTERM_UTF8_TEST2 == sys_write(1, xterm_utf8_test2, XTERM_UTF8_TEST2)) {
+ int row = -1, col = -1;
+ char buffer[32] = {0};
+ int len;
+
+ /*
+ * check cursor column after test string, determine screen mode
+ *
+ * 6 -> UTF-8, no double-width, with LAM/ALEF ligature joining
+ * 7 -> UTF-8, no double-width, no LAM/ALEF ligature joining
+ * 8 -> UTF-8, double-width, with LAM/ALEF ligature joining
+ * 9 -> UTF-8, double-width, no LAM/ALEF ligature joining
+ * 11,16 -> CJK terminal (with luit)
+ * 10,15 -> 8 bit terminal or CJK terminal
+ * 13 -> Poderosa terminal emulator, UTF-8, or TIS620 terminal
+ * 14,17 -> CJK terminal
+ * 16 -> Poderosa, ISO Latin-1
+ * (17) -> Poderosa, (JIS)
+ * 18 -> CJK terminal (or 8 bit terminal, e.g. Linux console)
+ */
+ if ((len = term_read(buffer, sizeof(buffer), -2)) >= 4) {
+ sscanf(buffer, "\033[%d;%dR", &row, &col);
+ }
+
+ trace_ilog("\tisutf8B(%d) = col:%d\n", len, col);
+ }
+}
+#endif /*XXX_MCHAR_DETECT*/
+
+
+/* Function: term_read
+ * Determine if the terminal supports UTF8 character encoding.
+ *
+ * Parameters:
+ * buf - Buffer.
+ * len - Length of the buffer, in bytes.
+ * tmo - Timeout is milliseconds.
+ *
+ * Returns:
+ * Number of bytes read.
+ */
+static int
+term_read(char *buf, int len, accint_t tmo)
+{
+ int ch, cnt = 0;
+
+ if (-2 == tmo) {
+ tmo = io_escdelay();
+ }
+
+ assert(buf);
+ assert(len);
+ assert(tmo >= -1);
+
+ --len;
+ if ((ch = io_get_raw(tmo)) > 0) {
+ do { /* secondary characters */
+ buf[cnt++] = (char) ch;
+ } while ((ch = io_get_raw(50)) > 0 && cnt < len);
+ }
+ buf[cnt] = '\0';
+ return cnt;
+}
+
+
+/* Function: term_tidy
+ * Cleanup/restore the state of the console.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_tidy(void)
+{
+ if (0 == tt_active)
+ return;
+
+ term_flush();
+
+ if (t_attributes & TA_CYGWIN) {
+ if (xf_cygwinkb) {
+ ttpush("\033[?2000l"); /* disable RAW mode */
+ }
+ } else if (t_attributes & TA_MINTTY) {
+//TODO if (! xf_mouse) {
+ ttpush("\033[?7786l"); /* disable mouse-wheel reports */
+// }
+ }
+
+ term_graphic_exit(); /* graphic mode */
+
+ term_colorreset();
+ term_styleoff();
+ xterm_colors_set(t_colorsorg);
+
+ /* ttputpad(tc_mo); -* restore meta key-codes */
+
+ ttputpad(tc_ve); /* restore normal cursor */
+
+ if (! xf_nokeypad) {
+ ttputpad(tc_ke); /* out of ``keypad-transmit'' mode */
+ }
+
+ if ((NULL == tc_rs && 0 == x_pt.pt_reset[0]) || x_pt.pt_noaltscreen) {
+ term_zero(TRUE); /* remove image */
+ ttmove(ttrows() - 1, 0);
+ } else {
+ term_scrollreset(); /* scroll window */
+ }
+
+ ttputpad(tc_rs); /* set the term back to normal mode */
+
+ if (x_pt.pt_reset[0]) { /* terminal specific reset */
+ ttputctl2(x_pt.pt_reset, 0, 0);
+ }
+ term_flush();
+
+ if (! xf_noinit) {
+ ttputpad(tc_te); /* disable cup (cursor addressing) */
+ }
+ term_flush();
+
+ trace_log("term_tidy(0x%0x)\n", t_specials);
+
+ tt_cursor = 0;
+ tt_active = 0;
+}
+
+
+/* Function: term_cursor
+ * Set the cursor status.
+ *
+ * Parameters:
+ * visible - Visible status.
+ * imode - Insert mode.
+ * virtual_space - Virtual space mode.
+ *
+ * Returns:
+ * returns the current visible status, otherwise -1 on error.
+ */
+static int
+term_cursor(int visible, int imode, int virtual_space)
+{
+ if (visible >= 0) {
+ if (visible != tt_cursor)
+ if (tc_vi && (tc_vs || tc_ve)) {
+ if (visible) { /* enable cursor, enhanced if available */
+ ttputpad(tc_vs ? tc_vs : tc_ve);
+ } else {
+ ttputpad(tc_vi); /* hide cursor */
+ }
+ }
+ tt_cursor = visible;
+ }
+
+ if (tt_cursor && imode >= 0) {
+ if (imode) { /* insert mode */
+ if (x_pt.pt_vicursor[0]) {
+ ttprintf(virtual_space ? x_pt.pt_vicursor : x_pt.pt_icursor);
+
+ } else if (x_pt.pt_xtcursor >= 1 ||
+ (-1 == x_pt.pt_xtcursor && (t_attributes & TA_XTERMLIKE))) {
+#if defined(DO_SPECIALS)
+ if (0 == (t_specials & 0x0010))
+ t_specials |= 0x0010, trace_log("SPECIAL(ttcursor) 'imode'\n");
+ ttprintf("\033]12;%s\007", "Black");
+#endif
+ }
+ } else { /* overstrike/overtype mode */
+ if (x_pt.pt_vocursor[0]) {
+ ttputpad(virtual_space ? x_pt.pt_vocursor : x_pt.pt_ocursor);
+
+ } else if (x_pt.pt_xtcursor >= 1 ||
+ (-1 == x_pt.pt_xtcursor && (t_attributes & TA_XTERMLIKE))) {
+#if defined(DO_SPECIALS)
+ if (0 == (t_specials & 0x0020)) {
+ t_specials |= 0x0020, trace_log("SPECIALS(ttcursor) 'omode'\n");
+ }
+ ttprintf("\033]12;%s\007", "RoyalBlue1");
+#endif
+ }
+ }
+ }
+
+ return (tt_cursor ? 1 : 0);
+}
+
+
+/* Function: ttmove
+ * Move the cursor to the specified origin 0 row and column position. Try to
+ * optimize out extra moves; redisplay may have left the cursor in the right
+ * location last time!
+ *
+ * Parameters:
+ * row - Screen row (0 .. rows - 1).
+ * col - Column (0 .. rows - 1).
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_move(int row, int col)
+{
+ const int rows = ttrows() - 1, cols = ttcols() - 1,
+ ttrow = ttatrow(), ttcol = ttatcol();
+
+ assert(row >= 0);
+ assert(row <= rows);
+ assert(col >= 0);
+ assert(col <= cols);
+
+ if (ttrow == row && ttcol == col) {
+ ED_TERM(("ttmove(%d,%d->%d,%d)\n", ttrow, ttcol, row, col))
+ return;
+ }
+ ED_TERM(("ttmove(%d,%d->%d,%d)", ttrow, ttcol, row, col))
+
+ /*
+ * Moving cursor, check ms flag.
+ * the 'ms' flag whose presence means that it is safe to move the cursor
+ * while the appearance modes are not in the normal state. If this flag
+ * is absent, programs should always turn off underlining/standout
+ * before moving the cursor.
+ */
+ if (1 != tf_ms)
+ if (tt_style) {
+ term_styleoff();
+ tt_hue = -1;
+ }
+
+ if (tc_ho && 0 == col && 0 == row) { /* */
+ ED_TERM(("->putpad(ho)\n"))
+ ttputpad(tc_ho);
+
+ } else {
+ /*
+ * optimise based on current position (if known)
+ */
+ int done = TRUE;
+
+ if (ttcol < 0 || ttrow < 0) {
+ /*
+ * invalid existing position.
+ */
+ done = FALSE;
+
+ } else if (tc_ll && row == rows && 0 == col) {
+ ED_TERM(("->putpad(ll)\n")) /* */
+ ttputpad(tc_ll);
+
+ } else {
+ /*
+ * If within column zero avoid using UP and DO under XTERM (others??)
+ * otherwise we shall find ourselves in the last column of the
+ * previous line; believe related to terminal automatic-margin
+ * support.
+ *
+ * Note: this is generally only a visible problem when running borderless mode.
+ */
+#define COLUMNOK() (col > 0 || 0 == (t_attributes & TA_XTERM))
+
+#define PCOST 4 /* parameterised version cost */
+
+ if (col == ttcol) { /* row changes */
+
+ /* cursor up - one line (ignore first column) */
+ if (tc_up && COLUMNOK() && row == ttrow - 1) {
+ ED_TERM(("->putpad(UP)\n"))
+ ttputpad(tc_up);
+
+ /* cursor up - parameterized (ignore first column) */
+ } else if (tc_pUP && COLUMNOK() && row < ttrow /*-PCOST*/) {
+ const int p1 = (int)(ttrow - row);
+
+ ED_TERM(("->putctl(pUP,%d)\n", p1))
+ ttputctl(tc_pUP, p1);
+
+ /* cursor down - one line (ignore bottom left corner) */
+ } else if (tc_do && COLUMNOK() && row == ttrow + 1 && (row < rows || col < (cols - 1))) {
+ ED_TERM(("->putpad(DO)\n"))
+ ttputpad(tc_do);
+
+ /* cursor down - parameterized */
+ } else if (tc_pDO && COLUMNOK() && row > ttrow /*+PCOST*/) {
+ const int p1 = (int)(row - ttrow);
+
+ ED_TERM(("->putctl(pDO,%d)\n", p1))
+ ttputctl(tc_pDO, p1);
+
+ /* cursor vertical movement */
+ } else if (tc_cv) {
+ ED_TERM(("->putctl(cv,%d)\n", row))
+ ttputctl(tc_cv, row);
+
+ } else {
+ done = FALSE;
+ }
+
+ } else if (row == ttrow) { /* column changes */
+
+ /* cursor left */
+ if (tc_cr && 0 == col) {
+ ED_TERM(("->putpad(cr)\n"))
+ ttputpad(tc_cr);
+
+ /* cursor left - one column */
+ } else if (tc_le && col < ttcol && col >= (ttcol - 3)) {
+ int p1 = (int)(ttcol - col);
+
+ ED_TERM(("->putpad(le,%d)\n", p1))
+ while (p1--) ttputpad(tc_le);
+
+ /* cursor back */
+ } else if (tc_bc && col < ttcol && col >= (ttcol - 3)) {
+ int p1 = (int)(ttcol - col);
+
+ ED_TERM(("->putpad(bc,%d)\n", p1))
+ while (p1-- > 0) ttputpad(tc_bc);
+
+ /* cursor left - parameterised */
+ } else if (tc_pBC && col < (ttcol - 2)) {
+ const int p1 = (int)(ttcol - col);
+
+ ED_TERM(("->putctl(pBC,%d)\n", p1))
+ ttputctl(tc_pBC, p1);
+
+ /* cursor right - one column */
+ } else if (tc_nd && col == ttcol + 1) {
+ ED_TERM(("->putpad(ND)\n"))
+ ttputpad(tc_nd);
+
+ /* cursor right - parameterised */
+ } else if (tc_pRI && col > ttcol && col > 1 && col < cols) {
+ const int p1 = (int)(col - ttcol);
+
+ ED_TERM(("->putctl(pRI,%d)\n", p1))
+ ttputctl(tc_pRI, p1);
+
+ /* cursor right - parameterised */
+ } else if (x_pt.pt_cursor_right[0] && col > ttcol /*+PCOST*/) {
+ const int p1 = (int)(col - ttcol);
+
+ ED_TERM(("->putctl(pCR,%d)\n", p1))
+ ttprintf(x_pt.pt_cursor_right, p1);
+
+ /* cursor horz movement */
+ } else if (tc_ch) {
+ ED_TERM(("->putctl(ch,%d)\n", col))
+ ttputctl(tc_ch, col);
+
+ } else {
+ done = FALSE;
+ }
+
+ } else {
+ done = FALSE; /* do by hand */
+ }
+ }
+
+#undef PCOST
+
+ /* absolute cursor movement */
+ if (! done) {
+ if (tc_cm) {
+ ED_TERM(("->cm(%d, %d)\n", col, row))
+ ttputctl2(tc_cm, col, row);
+ } else { /* use vertical/horiz movement */
+ ED_TERM(("->cvch(%d, d)\n", col, row))
+ ttputctl(tc_cv, row);
+ ttputctl(tc_ch, col);
+ }
+ }
+ }
+
+ ttposset(row, col);
+}
+
+
+/* Function: term_names
+ * Set the console title.
+ *
+ * Parameters:
+ * title - Title buffer.
+ *
+ * Returns:
+ * nothing.
+ */
+static int
+term_names(const char *title, const char *icon)
+{
+ __CUNUSED(icon)
+
+ if (x_pt.pt_xttitle >= 1 ||
+ (-1 == x_pt.pt_xttitle && (t_attributes & TA_XTERMLIKE))) {
+
+ const unsigned char *t = (const unsigned char *) title;
+ const size_t len = 16 + strlen(title);
+ char *c;
+
+ if (NULL != (c = chk_alloc(len))) {
+ unsigned char *p =
+ (unsigned char *)(c + sprintf(c, "\033]0;"));
+
+ do {
+ *p++ = (unsigned char)(*t < 32 || *t > 127 ? '?' : *t);
+ } while (*++t);
+ *p++ = '\007';
+ *p = '\0';
+
+ ttpush(c);
+ chk_free(c);
+ }
+ }
+ return 0;
+}
+
+
+/* Function: term_beep
+ * Make a noise.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_beep(int freq, int duration)
+{
+ __CUNUSED(freq) __CUNUSED(duration)
+
+ if (xf_visbell && tc_vb) { /* visual bell */
+ ttputpad(tc_vb);
+ } else if (tc_bl) {
+ ttputpad(tc_bl);
+ } else {
+ static const char bel[] = {ASCIIDEF_BEL, 0};
+ ttpush(bel);
+ }
+ term_flush();
+}
+
+
+/* Function: normalbg
+ * Determine whether the current background is the terminals
+ * default/normal background color.
+ *
+ * One of the following conditions are confirmed, checking the current
+ * hues ground against,
+ *
+ * o Background is the terminal default (see COLORFGBG and tt_defaultfg).
+ *
+ * o Background is NONE.
+ *
+ * Parameters:
+ * bg - Storage returned with the cooked color enumeration.
+ *
+ * Returns:
+ * *true* or *false*
+ */
+static int
+normalbg(int *bg)
+{
+ colattr_t ca;
+
+ *bg = -1;
+ color_definition(tt_hue, &ca);
+ return (COLORSOURCE_SYMBOLIC == ca.bg.source &&
+ (tt_defaultbg == (*bg = (int)tt_colormap[ca.bg.color]) || COLOR_NONE == ca.bg.color));
+}
+
+
+/* Function: clearbg
+ * Determine whether a terminal clear command will (hopefully) function correctly with
+ * the current background color, otherwise the operation shall fail resulting in the
+ * cleared region being an incorrect background color; hence should be avoided.
+ *
+ * One of the following conditions are confirmed,
+ *
+ * o BE or UT, if BE (Back color erase - xterm) or UT (Screen erased with background
+ * color) are true the terminal clears using the current hue.
+ *
+ * o Current hue is the terminals default/normal background.
+ *
+ * o Terminal feature clrisblack is enabled and background is BLACK.
+ *
+ * o No color mode and the hue is NORMAL.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static int
+clearbg(void)
+{
+ int bg;
+
+ if (tf_be || tf_ut)
+ return TRUE; /* erase in current color */
+ if (normalbg(&bg))
+ return TRUE; /* current background is normal/default */
+ if (x_pt.pt_clrisblack && BLACK == bg) {
+ return TRUE;
+ }
+ if (!vtiscolor() && ATTR_NORMAL == tt_hue) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* Function: term_clear
+ * Clear the terminal.
+ *
+ * Parameters:
+ * restore - *true* if the screen image should be restored.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_clear(void)
+{
+ ED_TERM(("term_clear()\n"))
+ term_zero(FALSE);
+}
+
+
+/* Function: term_zero
+ * Zero the terminal image.
+ *
+ * Parameters:
+ * restore - *true* if the screen image should be restored.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_zero(int restore)
+{
+ ED_TERM(("term_zero(%d)\n", restore))
+ term_scrollreset();
+ ttmove(0, 0);
+ term_attr(VBYTE_ATTR(ATTR_NORMAL));
+ if (tc_cl && (restore || clearbg())) { /* clear screen command (and home cursor) */
+ ED_TERM(("->putpad(CL)\n"))
+ ttputpad(tc_cl);
+ } else { /* erase to end of page */
+ ED_TERM(("->eeop()\n"))
+ term_eeop(restore);
+ }
+ term_colorreset();
+ term_flush();
+}
+
+
+/* Function: term_eeol
+ * Erase to end of line in the 'current' color.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * *true* if eeol successful, otherwise *false*.
+ */
+static int
+term_eeol(void)
+{
+ const int rows = ttrows() - 1, cols = ttcols() - 1,
+ row = ttatrow(), col = ttatcol();
+
+ ED_TERM(("term_eeol(%d, %d)\n", row, col))
+
+ assert(row <= rows);
+ assert(col <= cols);
+
+ if (col < cols) {
+ /*
+ * Clear to end of line.
+ */
+ if (term_ce() && clearbg()) {
+ ED_TERM(("->putpad(CE)\n"))
+ ttputpad(tc_ce);
+
+ /*
+ * Character based
+ * Avoid writing to the lower right corner; as the terminal does not have CE,
+ * then it probably does not have what it takes not to scroll upon hitting
+ * the bottom-right corner.
+ */
+ } else {
+ int cnt = cols - col; /* column count to end-of-line */
+
+ if (row >= rows) {
+ --cnt; /* ignore last column */
+ }
+ term_repeat(cnt, ' ' | VBYTE_ATTR(tt_hue), WHERE_START);
+ }
+ }
+ return TRUE;
+}
+
+
+/* Function: term_ce
+ * Is clear to end of line (CE) available.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static int
+term_ce(void)
+{
+ return (tc_ce && tc_ce[0]);
+}
+
+
+/* Function: term_lastsafe
+ * Return whether it is safe to write to the last character within the bottom column.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * TRUE or FALSE.
+ */
+static int
+term_lastsafe(void)
+{
+ if (TA_CYGWIN & t_attributes) {
+ return FALSE; /* needs further investigations */
+ }
+ return (term_ce() || tf_LP > 0 ? TRUE : FALSE);
+}
+
+
+/* Function: term_eeop
+ * Erase to end of page.
+ *
+ * Parameters:
+ * restore - Executed during a restore operation.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_eeop(int restore)
+{
+ const int rows = ttrows() - 1, cols = ttcols() - 1;
+ int row = ttatrow(), col = ttatcol();
+
+ ED_TERM(("term_eeop(%d, %d)\n", row, col))
+
+ assert(row <= rows);
+ assert(col <= cols);
+
+ if (tc_cd && (restore || clearbg())) { /* clear to end of display (cursor unchanged). */
+ ED_TERM(("->putpad(CD)\n"))
+ ttputpad(tc_cd);
+
+ } else { /* long-hand */
+ int done = FALSE;
+
+ if (col > 0) {
+ term_eeol(); /* remove remaining of line */
+ ++row;
+ }
+
+ if (row <= rows) {
+ if (t_insdel && !x_pt.pt_noinsdel && (restore || clearbg())) {
+ done = term_dell(row, rows, rows - row, 0 /*current*/);
+ if (done) {
+ ED_TERM(("->ttdell()\n"))
+ }
+ }
+
+ if (! done) { /* do it by hand. */
+ ED_TERM(("->line-by-line()\n"))
+ for (; row <= rows; ++row) {
+ ttmove(row, 0);
+ term_eeol();
+ }
+ }
+ }
+ }
+}
+
+
+/* Function: term_repeat
+ * Function to repeat a character from the current location.
+ *
+ * 'where' says whether we want the cursor to stick at the starting point or stick
+ * at the end of the region. If set to 2 then this is a don't care -- i.e. leave
+ * cursor as it is.
+ *
+ * Parameters:
+ * cnt - Character count.
+ * fill - Fill character.
+ * where - Where to leave the cursor (0=end, 1=start, 2=dontcare).
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_repeat(int cnt, vbyte_t fill, int where)
+{
+ const int orow = ttatrow(), ocol = ttatcol();
+
+ ED_TERM(("term_repeat(%d,'%c')\n", cnt, VBYTE_CHAR_GET(fill)))
+
+ if (cnt <= 0) return;
+
+ term_attr(fill & VBYTE_ATTR_MASK);
+
+ if (cnt >= (4 + (WHERE_DONTCARE == where ? 0 : 4))) {
+ const int ch = (int) VBYTE_CHAR_GET(fill);
+ int bg = 0;
+ /* erase #1 characters (no cursor move) */
+ if (tc_ech && ' ' == ch && normalbg(&bg)) {
+
+ if (0 == (t_specials & 0x0001))
+ t_specials |= 0x0001, trace_log("SPECIAL(erase-repeat,%s,%d)\n", tc_ech, cnt);
+
+ ttputctl(tc_ech, cnt);
+ ttposinvalid();
+ if (WHERE_END == where) {
+ ttmove(orow, ocol + cnt);
+ } else if (WHERE_START == where) {
+ ttmove(orow, ocol);
+ }
+ cnt = 0;
+ /* repeat character (cursor move) */
+ } else if (tc_rp && (orow < (ttrows() - 1))) {
+
+ if (0 == (t_specials & 0x0002))
+ t_specials |= 0x0002, trace_log("SPECIAL(repeat-char,%s,%d)\n", tc_rp, cnt);
+
+ ttputctl2(tc_rp, cnt, ch);
+ ttposinvalid();
+ if (WHERE_END == where) {
+ ttmove(orow, ocol + cnt);
+ } else if (WHERE_START == where) {
+ ttmove(orow, ocol);
+ }
+ cnt = 0;
+ /* erase #1 characters (no cursor move) */
+ } else if (x_pt.pt_repeat_space[0] && ' ' == ch && normalbg(&bg)) {
+
+ if (0 == (t_specials & 0x0004))
+ t_specials |= 0x0004, trace_log("SPECIAL(erase-repeat,%s)\n", x_pt.pt_repeat_space);
+
+ ttprintf(x_pt.pt_repeat_space, cnt);
+ ttposinvalid();
+ if (WHERE_END == where) {
+ ttmove(orow, ocol + cnt);
+ } else if (WHERE_START == where) {
+ ttmove(orow, ocol);
+ }
+ cnt = 0;
+
+ } else if (x_pt.pt_repeat_last[0] && /* repeat last (cursor move *not* assumed) */
+ (orow < (ttrows() - 1)) && normalbg(&bg)) {
+
+ if (0 == (t_specials & 0x0008))
+ t_specials |= 0x0008, trace_log("SPECIAL(repeat-last,%s,%d)\n", x_pt.pt_repeat_last, cnt);
+
+ term_putc(fill);
+ ttprintf(x_pt.pt_repeat_last, cnt - 1);
+ ttposinvalid();
+ if (WHERE_END == where) {
+ ttmove(orow, ocol + cnt);
+ } else if (WHERE_START == where) {
+ ttmove(orow, ocol);
+ }
+ cnt = 0;
+ }
+ }
+
+ if (cnt > 0) { /* by-hand */
+ ED_TERM(("->byhand()\n"))
+ while (cnt-- > 0) {
+ term_putc(fill);
+ }
+ if (WHERE_START == where) {
+ ttmove(orow, ocol);
+ }
+ }
+}
+
+
+/* Function: term_insl
+ * Insert the specified number of blank lines 'lines' onto the screen using the region
+ * 'row' and 'bot', scrolling the last line within the region off the screen.
+ *
+ * Use the scrolling region commands if possible for a smoother display, otherwise
+ * when no scrolling region, use a set of insert and delete line sequences.
+ *
+ * Parameters:
+ * row - Top row of region.
+ * bot - Bottom of region.
+ * nlines - Number of lines to be inserted.
+ * fillcolor - Fill attribute.
+ *
+ * Returns:
+ * TRUE if the operation could be performed, otherwise FALSE.
+ */
+static int
+term_insl(int row, int bot, int nlines, vbyte_t fillcolor)
+{
+ int i;
+
+ trace_log("term_insl(row:%d, bot:%d, nlines:%d)\n", row, bot, nlines);
+
+ assert(row >= 0);
+ assert(bot >= 0);
+ assert(row < ttrows());
+ assert(bot < ttrows());
+ assert(bot >= row);
+ assert(nlines > 0);
+ assert(nlines <= (bot - row));
+
+ term_attr(fillcolor);
+
+ if (row == bot) { /* one line, simple optimisation */
+ ttmove(row, 0);
+ term_eeol();
+ return TRUE;
+ }
+ /* scroll region and back index */
+ if (tc_cs && tc_sr && !x_pt.pt_scroll_disable) {
+ term_scrollset(row, bot);
+ ttmove(row, 0);
+ if (nlines > 1 && tc_pSR) {
+ ttputctl(tc_pSR, nlines);
+ } else {
+ for (i = 0; i < nlines; ++i) {
+ ttputpad(tc_sr), term_eeol();
+ }
+ }
+ term_scrollreset();
+ ttmove(row, 0);
+ return TRUE;
+ }
+
+ if (t_insdel && !x_pt.pt_noinsdel) { /* line ins/del */
+ ttmove(1 + bot - nlines, 0);
+ if (nlines > 1 && tc_pDL) {
+ ttputctl(tc_pDL, nlines);
+ } else {
+ for (i = 0; i < nlines; ++i) {
+ ttputpad(tc_dl);
+ }
+ }
+
+ ttmove(row, 0);
+ if (nlines > 1 && tc_pAL) {
+ ttputctl(tc_pAL, nlines);
+ } else {
+ for (i = 0; i < nlines; ++i) {
+ ttputpad(tc_al);
+ }
+ }
+
+ if (!tf_be || !tf_ut) /* must erase line for correct colouring */
+ for (i = 0; i < nlines; ++i) {
+ ttmove(row + i, 0);
+ term_eeol();
+ }
+
+ ttposinvalid();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* Function: term_dell
+ * Delete the specified number of blank lines 'nlines' onto the screen using the region
+ * 'row' and 'bot', replacing the last line within a blank line.
+ *
+ * Use the scrolling region commands if possible for a smoother display, otherwise
+ * when no scrolling region, use a set of insert and delete line sequences.
+ *
+ * Knownledge that the echo-line shall always be presence, removes the end-of-screeen
+ * boundary condition.
+ *
+ * Parameters:
+ * row - Top row of region.
+ * bot - Bottom of region.
+ * nlines - Number of lines to be deleted.
+ * fillcolor - Fill attribute.
+ *
+ * Returns:
+ * TRUE if the operation could be performed, otherwise FALSE.
+ */
+static int
+term_dell(int row, int bot, int nlines, vbyte_t fillcolor)
+{
+ int i;
+
+ trace_log("term_dell(row:%d, bot:%d, nlines:%d)\n", row, bot, nlines);
+
+ assert(row >= 0);
+ assert(bot >= 0);
+ assert(row < ttrows());
+ assert(bot < ttrows());
+ assert(bot >= row);
+ assert(nlines > 0);
+ assert(nlines <= (bot - row));
+
+ term_attr(fillcolor);
+
+ if (row == bot) { /* one line special case */
+ ttmove(row, 0);
+ term_eeol();
+ return TRUE;
+ }
+
+ if (tc_cs && !x_pt.pt_scroll_disable && /* scrolling region and within limits */
+ (x_pt.pt_scroll_max <= 2 || (bot - row) <= x_pt.pt_scroll_max)) {
+ term_scrollset(row, bot);
+ ttmove(bot, 0);
+ if (nlines > 1 && tc_pSF) {
+ ttputctl(tc_pSF, nlines); /* 24/11/08 */
+ } else {
+ for (i = 0; i < nlines; ++i) {
+ ttputpad(tc_sf ? tc_sf : "\n"), term_eeol();
+ }
+ }
+ term_scrollreset();
+ ttmove(bot, 0);
+ return TRUE;
+ }
+ /* ins/del, unless disabled or fast */
+ if (t_insdel && !x_pt.pt_noinsdel && x_pt.pt_tty_fast <= 0) {
+ ttmove(row, 0);
+ if (nlines > 1 && tc_pDL) {
+ ttputctl(tc_pDL, nlines);
+ } else {
+ for (i = 0; i < nlines; ++i) {
+ ttputpad(tc_dl);
+ }
+ }
+ ttmove(1 + bot - nlines, 0);
+ if (nlines > 1 && tc_pAL) {
+ ttputctl(tc_pAL, nlines);
+ } else {
+ for (i = 0; i < nlines; ++i) {
+ ttputpad(tc_al);
+ }
+ }
+ ttposinvalid();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* Function: term_scrollset
+ * Setup the display scrolling window.
+ *
+ * Note:
+ * Setting a scroll region invalidates the cursor position. As such the cursor
+ * position is also invalidated to ensure that the next call to "ttmove" does
+ * not turn into a no-op (the window adjustment moves the cursor).
+ *
+ * Parameters:
+ * top - Top row of the scroll region.
+ * bot - Bottom row.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_scrollset(int top, int bot)
+{
+ assert(top >= 0);
+ assert(top < ttrows());
+ assert(bot >= 0);
+ assert(bot < ttrows());
+ assert(-1 == top || top != bot); /* one line, should be avoided */
+ assert(top < bot);
+ assert(tc_cs); /* should always be the case */
+
+ if (tc_cs) { /* scroll region avail ? */
+ if (-1 == top || -1 == bot) {
+ top = 0, bot = ttrows() - 1; /* reset */
+ }
+
+ if (tt_top != top || tt_bot != bot) { /* update */
+ ttputctl2(tc_cs, tt_bot = bot, tt_top = top);
+ ttposinvalid();
+ }
+ }
+}
+
+
+/* Function: term_scrollreset
+ * Reset the current scroll region.
+ *
+ * Note:
+ * Setting a scroll region invalidates the cursor position. As such the cursor
+ * position is also invalidated to ensure that the next call to "ttmove" does
+ * not turn into a no-op (the window adjustment moves the cursor).
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_scrollreset(void)
+{
+ if (tc_cs) {
+ ttputctl2(tc_cs, tt_bot = ttrows() - 1, tt_top = 0);
+ ttposinvalid();
+ }
+}
+
+
+/* Function: term_attr
+ * Set the current attribute color to the specified color.
+ *
+ * The following function optimises based on the required color change and the
+ * current known state (if any).
+ *
+ * Parameters:
+ * color - Required color attribute.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_attr(vbyte_t color)
+{
+ vbyte_t attr = VBYTE_ATTR_GET(color); /* encode attribute */
+
+ if (tt_hue == attr) {
+ return;
+ }
+ tt_hue = attr;
+
+ ED_TERM(("ttattr(%d/0x%x)", attr, attr))
+
+ if (! vtiscolor()) {
+ /*
+ * black-wbite/no-color mode
+ * \033[0m Normal.
+ * \033[1m Bold (extra bright).
+ * \033[4m Underline.
+ * \033[5m Blink (appears as Bold on Xterm etc).
+ * \033[7m Inverse (hilight).
+ *
+ * optional:
+ * \033[22m Normal (neither bold nor faint).
+ * \033[24m End underline.
+ */
+ const int nstyle = ttbandw(attr, tc_us?1:0, tc_ZH?1:0, tc_mb?1:0);
+
+ if (tt_style != nstyle) {
+ term_styleoff();
+ term_styleon(nstyle);
+ }
+
+ } else {
+ colattr_t ca = {0};
+ int fg, bg, sf;
+
+ color_definition(attr, &ca);
+ fg = ca.fg.color;
+ bg = ca.bg.color;
+ sf = ca.sf;
+
+ ED_TERM((", curr(fg:%d, bg:%d, sf:%d), attr(fg:%d, bg:%d, sf:%d)", tt_fg, tt_bg, tt_style, fg, bg, sf))
+
+ if (tt_colors >= 88 /*88 or 256*/) {
+ /* 256 color mode
+ *
+ * \033[0m Set normal (foreground, background and styles)
+ * \033[39m Normal foreground color.
+ * \033[49m Normal background color.
+ * \033[38;5;#m Set the foreground color to index #
+ * \033[48;5;#m Set the background color to index #
+ */
+ if (COLORSOURCE_SYMBOLIC == ca.fg.source) fg = tt_colormap[fg];
+ if (COLORSOURCE_SYMBOLIC == ca.bg.source) bg = tt_colormap[bg];
+
+ ED_TERM(("->map(fg:%d, bg:%d)", fg, bg))
+
+ if (fg != tt_fg || bg != tt_bg || sf != tt_style) {
+ char ebuf[64];
+
+ if (tt_style) term_styleoff();
+
+ if (fg >= 0 && bg >= 0) { /* foreground,background */
+ // if (x_pt.pt_colorsetfgbg[0]) {
+ // sxprintf(ebuf, sizeof(ebuf), x_pt.pt_colorsetfgbg, 0xff & fg, 0xff & bg);
+ //
+ // } else if (x_pt.pt_colorsetfg[0] && x_pt.pt_colorsetbg[0]) {
+ // int len = sxprintf(ebuf, sizeof(ebuf), x_pt.pt_colorsetfg, 0xff & fg);
+ // sxprintf(ebuf + len, sizeof(ebuf) - len, x_pt.pt_colorsetbg, 0xff & bg);
+ //
+ // } else {
+ sxprintf(ebuf, sizeof(ebuf), "\033[38;5;%u;48;5;%um", 0xff & fg, 0xff & bg);
+ // }
+ ttputpad(ebuf);
+
+ } else if (fg >= 0) { /* foreground,normal */
+ // if (x_pt.pt_colorsetfgbg[0]) {
+ // sxprintf(ebuf, sizeof(ebuf), x_pt.pt_colorsetfgbg, 0xff & fg, 0);
+ //
+ // } else if (x_pt.pt_colorsetfg[0] && x_pt.pt_colorsetbg[0]) {
+ // int len = sxprintf(ebuf, sizeof(ebuf), x_pt.pt_colorsetfg, 0xff & fg);
+ // sxprintf(ebuf + len, sizeof(ebuf) - len, x_pt.pt_colorsetbg, 0);
+ //
+ // } else {
+ sxprintf(ebuf, sizeof(ebuf), "\033[49;38;5;%um", 0xff & fg);
+ // }
+ ttputpad(ebuf);
+
+ } else if (bg >= 0) { /* normal,background */
+ // if (x_pt.pt_colorsetfgbg[0]) {
+ // sxprintf(ebuf, sizeof(ebuf), x_pt.pt_colorsetfgbg, 0, 0xff & bg);
+ //
+ // } else if (x_pt.pt_colorsetfg[0] && x_pt.pt_colorsetbg[0]) {
+ // int len = sxprintf(ebuf, sizeof(ebuf), x_pt.pt_colorsetfg, 0);
+ // sxprintf(ebuf + len, sizeof(ebuf) - len, x_pt.pt_colorsetbg, 0xff & bg);
+ //
+ // } else {
+ sxprintf(ebuf, sizeof(ebuf), "\033[39;48;5;%um", 0xff & bg);
+ // }
+ ttputpad(ebuf);
+
+ } else { /* normal */
+ sxprintf(ebuf, sizeof(ebuf), "\033[0m");
+ ttputpad(tc_me ? tc_me : "\033[0m");
+ }
+
+ if (sf) term_styleon(sf);
+ }
+
+ } else if (tt_colors > 8 || NULL == tc_Color_Bg || NULL == tc_Color_Fg) {
+ /* 16 color mode (standard - ANSI)
+ *
+ * \033[0m Set normal (foreground and background)
+ *
+ * \033[30m Set foreground color to Black
+ * \033[31m Set foreground color to Red
+ * \033[32m Set foreground color to Green
+ * \033[33m Set foreground color to Yellow
+ * \033[34m Set foreground color to Blue
+ * \033[35m Set foreground color to Magenta
+ * \033[36m Set foreground color to Cyan
+ * \033[37m Set foreground color to White
+ * \033[1;%dm Set foreground color (bright, 30 .. 37)
+ *
+ * \033[40m Set background color to Black
+ * \033[41m Set background color to Red
+ * \033[42m Set background color to Green
+ * \033[43m Set background color to Yellow
+ * \033[44m Set background color to Blue
+ * \033[45m Set background color to Magenta
+ * \033[46m Set background color to Cyan
+ * \033[47m Set background color to White
+ * \033[5;%dm Set background color (bright, 40 -- 47)
+ *
+ */
+ char ebuf[48] = "\033["; /* leading */
+ int l = 2;
+
+ if (COLORSOURCE_SYMBOLIC == ca.fg.source) fg = tt_colormap[fg];
+ if (COLORSOURCE_SYMBOLIC == ca.bg.source) bg = tt_colormap[bg];
+ if (fg == bg && bg >= 0) {
+ if (TA_DARK & t_attributes) {
+ fg = tt_colormap[WHITE];
+ bg = tt_colormap[BLACK];
+ } else {
+ fg = tt_colormap[BLACK];
+ bg = tt_colormap[WHITE];
+ }
+ }
+
+ /* do we need/can reset to normal */
+ if (fg < 0 || bg < 0) {
+ strcpy(ebuf+l, "0;"); /* normal */
+ tt_fg = (fg < 0 ? fg : NOCOLOR);
+ tt_bg = (bg < 0 ? bg : NOCOLOR);
+ tt_style = 0;
+ l += 2;
+
+ } else {
+ if ((NOCOLOR == tt_fg) ||
+ (!(bg & 0x8) && (tt_bg & 0x8)) || (!(fg & 0x8) && (tt_fg & 0x8)) ||
+ (tt_defaultfg == fg && fg != tt_fg) || (tt_defaultbg == bg && bg != tt_bg)) {
+ strcpy(ebuf+l, "0;"); /* normal */
+ tt_fg = (tt_defaultfg == fg ? fg : NOCOLOR);
+ tt_bg = (tt_defaultbg == bg ? bg : NOCOLOR);
+ tt_style = 0;
+ l += 2;
+ }
+ }
+
+ if (tt_style != sf && tt_style) {
+ term_styleoff();
+ }
+
+ /* color selection */
+ if (fg != tt_fg) { /* foreground 30 - 37 */
+ l += sprintf(ebuf+l, (fg & 8) ? "1;%u" : "%u", 30 + (fg & 7));
+ }
+
+ if (bg != tt_bg) { /* background 40 - 47 */
+ if (l > 2) {
+ ebuf[l++] = ';';
+ }
+ l += sprintf(ebuf+l, (bg & 8) ? "5;%u" : "%u", 40 + (bg & 7));
+ }
+
+ if (l > 2) { /* flush result */
+ ebuf[l++] = 'm';
+ ebuf[l++] = 0;
+ assert(l < (int)sizeof(ebuf));
+ ttputpad(ebuf);
+ }
+
+ if (tt_style != sf) {
+ term_styleon(sf); /* style changes */
+ }
+
+ } else if (tc_Color_Fg == tc_ANSI_Color_Fg) {
+ /*
+ * ANSI - 16+8 color mode
+ */
+ if (COLORSOURCE_SYMBOLIC == ca.fg.source) fg = color_map[fg].c16;
+ if (COLORSOURCE_SYMBOLIC == ca.bg.source) bg = color_map[bg].c16;
+ if (fg == bg && bg >= 0) {
+ if (TA_DARK & t_attributes) {
+ fg = color_map[WHITE].c16;
+ bg = color_map[BLACK].c16;
+ } else {
+ fg = color_map[BLACK].c16;
+ bg = color_map[WHITE].c16;
+ }
+ }
+
+ if (fg < 0 || bg < 0) {
+ ttputpad(tc_me ? tc_me : "\033[0m");
+ tt_fg = (fg < 0 ? fg : NOCOLOR);
+ tt_bg = (bg < 0 ? bg : NOCOLOR);
+ tt_style = 0;
+ }
+
+ if (tt_style != sf && tt_style) {
+ term_styleoff();
+ }
+
+ if (fg != tt_fg) {
+ ttputpad((fg & 0x8) ? tc_md : tc_se);
+ ttputctl(tc_Color_Fg, (fg & 7));
+ }
+
+ if (bg != tt_bg) {
+ ttputctl(tc_Color_Bg, (bg & 7));
+ }
+
+ if (tt_style != sf) {
+ term_styleon(sf); /* style changes */
+ }
+
+ } else {
+ /*
+ * PC - 16+8 color mode
+ */
+ if (COLORSOURCE_SYMBOLIC == ca.fg.source) fg = color_map[fg].c16_pc;
+ if (COLORSOURCE_SYMBOLIC == ca.bg.source) bg = color_map[bg].c16_pc;
+ if (fg == bg && bg >= 0) {
+ if (TA_DARK & t_attributes) {
+ fg = color_map[WHITE].c16_pc;
+ bg = color_map[BLACK].c16_pc;
+ } else {
+ fg = color_map[BLACK].c16_pc;
+ bg = color_map[WHITE].c16_pc;
+ }
+ }
+
+ if (fg < 0 || bg < 0) {
+ ttputpad(tc_me ? tc_me : "\033[0m");
+ tt_fg = (fg < 0 ? fg : NOCOLOR);
+ tt_bg = (bg < 0 ? bg : NOCOLOR);
+ tt_style = 0;
+ }
+
+ if (tt_style != sf && tt_style) {
+ term_styleoff();
+ }
+
+ if (fg != tt_fg) {
+ ttputpad((fg & 0x8) ? tc_md : tc_se);
+ ttputctl(tc_Color_Fg, fg & 7);
+ }
+
+ if (bg != tt_bg) {
+ ttputctl(tc_Color_Bg, bg & 7);
+ }
+
+ if (tt_style != sf) {
+ term_styleon(sf); /* style changes */
+ }
+ }
+
+ tt_fg = fg;
+ tt_bg = bg;
+ }
+
+ ED_TERM(("\n"))
+}
+
+
+/* Function: term_styleon
+ * Enable the states styles.
+ *
+ * Parameters:
+ * ntype - New style bitmap.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_styleon(unsigned nstyle)
+{
+ if (vtiscolor() && tn_NC > 0) {
+ return; /* XXX - color/attributes dont mix, should mask */
+ }
+
+#if defined(HAVE_TERMINFO)
+ if (tc_sa && !vtiscolor()) {
+ ttputpad(tparm((char *)tc_sa, /* attribute set, mono only */
+ /*STANDOUT*/ (nstyle & (COLORSTYLE_STANDOUT|COLORSTYLE_INVERSE)) != 0,
+ /*UNDERLINE*/ (nstyle & COLORSTYLE_UNDERLINE) != 0,
+ /*REVERSE*/ (nstyle & COLORSTYLE_REVERSE) != 0,
+ /*BLINK*/ (nstyle & COLORSTYLE_BLINK) != 0,
+ /*DIM*/ (nstyle & COLORSTYLE_DIM) != 0,
+ /*BOLD*/ (nstyle & COLORSTYLE_BOLD) != 0,
+ /*INVISIBLE*/ 0,
+ /*PROTECT*/ 0,
+ /*ALTCHAR*/ (t_gmode ? 1 : 0)));
+ tt_style |= nstyle;
+ return;
+ }
+#endif /*HAVE_TERMINFO*/
+
+#define ACTIVATE_STYLE(x) \
+ ((nstyle & (x)) && 0 == (tt_style & (x)))
+
+ if (ACTIVATE_STYLE(COLORSTYLE_STANDOUT)) {
+ ttputpad(tc_so); /* standout mode. */
+ } else if (ACTIVATE_STYLE(COLORSTYLE_INVERSE)) {
+ ttputpad(tc_so);
+ }
+
+ if (ACTIVATE_STYLE(COLORSTYLE_REVERSE)) {
+ ttputpad(tc_mr ? tc_mr : tc_so); /* reverse */
+ }
+
+ if (ACTIVATE_STYLE(COLORSTYLE_UNDERLINE)) {
+ ttputpad(tc_us); /* underline */
+ }
+
+ if (ACTIVATE_STYLE(COLORSTYLE_BOLD)) {
+ ttputpad(tc_md); /* bold */
+ }
+
+ if (ACTIVATE_STYLE(COLORSTYLE_BLINK)) {
+ ttputpad(tc_mb); /* blink */
+ }
+
+ if (ACTIVATE_STYLE(COLORSTYLE_ITALIC)) {
+ ttputpad(tc_ZH); /* italic */
+ }
+
+ tt_style |= nstyle;
+}
+
+
+/* Function: term_styleoff
+ * Disable any current styles.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_styleoff(void)
+{
+ if (tt_style && tc_me) { /* simple */
+ ttputpad(tc_me);
+
+ } else { /* case-by-case */
+ if (tt_style & (COLORSTYLE_STANDOUT|COLORSTYLE_INVERSE|COLORSTYLE_BOLD|COLORSTYLE_BLINK)) {
+ /*
+ * end standout mode
+ */
+ if (tc_se == tc_ZH) tt_style &= (unsigned)(~COLORSTYLE_REVERSE);
+ if (tc_se == tc_ue) tt_style &= (unsigned)(~COLORSTYLE_UNDERLINE);
+ if (tc_se == tc_ZR) tt_style &= (unsigned)(~COLORSTYLE_ITALIC);
+ ttputpad(tc_se); /* inverse, bold ... */
+ }
+
+ if (tt_style & COLORSTYLE_REVERSE) {
+ ttputpad(tc_ZX); /* reverse */
+ }
+
+ if (tt_style & COLORSTYLE_UNDERLINE) { /* underline */
+ ttputpad(tc_ue);
+ }
+
+ if (tt_style & COLORSTYLE_ITALIC) { /* italic */
+ ttputpad(tc_ZR);
+ }
+ }
+ tt_style = 0;
+}
+
+
+/* Function: term_colorreset
+ * Reset the terminal color to the system default.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_colorreset(void)
+{
+ ttputpad(tc_me ? tc_me : "\033[0m");
+ tt_fg = tt_bg = NOCOLOR;
+ tt_hue = 0;
+}
+
+
+/* Function: putfakech
+ * Fake character output support callback for term_cost().
+ *
+ * Parameters:
+ * c - Character value.
+ *
+ * Returns:
+ * Always zero.
+ */
+static int
+putfakech(TPUTS_OUTTYPE c)
+{
+ (void)c;
+ ++t_cost;
+ return 0;
+}
+
+
+/* Function: term_cost
+ * Calculate the cost of displaying the specified string 'str'.
+ *
+ * Parameters:
+ * str - Control sequence.
+ *
+ * Returns:
+ * cost in characters.
+ */
+static int
+term_cost(const char *str)
+{
+ t_cost = 0;
+ tputs((char *)str, ttrows(), TPUTS_OUTFUNC putfakech);
+ return t_cost;
+}
+
+
+/* Function: putpadch
+ * termcap ttputpad() callback.
+ *
+ * Parameters:
+ * ch - Character value.
+ *
+ * Returns:
+ * Always zero,
+ */
+static int
+putpadch(TPUTS_OUTTYPE ch)
+{
+ if (ch == t_padchar && x_pt.pt_tty_fast > 0) {
+ return 0; /* consume padding characters */
+ }
+ if (t_count >= sizeof(t_buffer)) {
+ panic("ttputpad buffer overflow.");
+ }
+ t_buffer[ t_count++ ] = (unsigned char)ch;
+ return 0;
+}
+
+
+/* Function: ttputpad
+ * termcap/terminfo output primitive.
+ *
+ * Parameters:
+ * str - Control sequence.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+ttputpad(const char *str)
+{
+ if (str && str[0]) {
+ if (t_count + strlen(str) >= NOBUF) {
+ term_flush();
+ }
+ ED_TRACE3(("ttputpad(\"%s\")\n", str))
+ tputs((char *)str, 1, TPUTS_OUTFUNC putpadch);
+ }
+}
+
+
+/* Function: ttputctl
+ * termcap/terminfo print output primitive.
+ *
+ * Parameters:
+ * str - Control sequence.
+ * p1 - Argument.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+ttputctl(const char *str, int p1)
+{
+ if (str && str[0]) {
+#if defined(HAVE_TERMINFO)
+ ttputpad(tparm((char *)str, p1, 0));
+#else
+ ttputpad(tgoto((char *)str, 0, p1));
+#endif
+ }
+}
+
+
+/* Function: ttputctl2
+ * termcap/terminfo print output primitive.
+ *
+ * Parameters:
+ * str - Control sequence.
+ * p2 - Second parameter.
+ * p1 - First parameter.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+ttputctl2(const char *str, int p2, int p1)
+{
+ if (str && str[0]) {
+#if defined(HAVE_TERMINFO)
+ ttputpad(tparm((char *)str, p1, p2, 0));
+#else
+ ttputpad(tgoto((char *)str, p2, p1));
+#endif
+ }
+}
+
+
+/* Function: ttprintf
+ * Non-termcap print output primitive.
+ *
+ * Parameters:
+ * str - Format specification.
+ * ... - optional argument.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+ttprintf(const char *str, ...)
+{
+ va_list ap;
+ char buf[512];
+
+ va_start(ap, str);
+ vsxprintf(buf, sizeof(buf), str, ap);
+ ttputpad(buf);
+ va_end(ap);
+}
+
+
+/* Function: ttpush
+ * Push characters into the output buffer.
+ *
+ * Parameters:
+ * cp - Character buffer.
+ *
+ * Returns:
+ * nothing.
+ */
+void
+ttpush(const char *cp)
+{
+ const int len = strlen(cp);
+
+ if ((t_count + len) > sizeof(t_buffer)) {
+ panic("ttpush buffer overflow.");
+ }
+ memcpy(t_buffer + t_count, cp, len);
+ t_count += len;
+}
+
+
+/* Function: ttputc
+ * Write character to the display.
+ *
+ * Characters are buffered up, to make things a little bit more efficient.
+ *
+ * Parameters:
+ * c - Character value.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_putc(vbyte_t c)
+{
+ const int rows = ttrows() - 1, cols = ttcols() - 1;
+ int ttrow = ttatrow(), ttcol = ttatcol();
+ int width = 1;
+
+ assert(ttrow <= rows);
+ assert(ttcol <= cols);
+
+ if (t_count >= (NOBUF - (MCHAR_MAX_LENGTH * 2))) {
+ term_flush();
+ }
+
+ /*
+ * colorize
+ */
+ term_attr(c & VBYTE_ATTR_MASK);
+ c &= VBYTE_CHAR_MASK;
+ if (0 == c) { /* color-change only */
+ return;
+ }
+
+ /*
+ * UNICODE and special characters
+ */
+ if (c >= 0x80) {
+ const int isutf8 = vtisutf8();
+
+ /*
+ * internal characters
+ */
+ if (c >= CH_MIN && c <= CH_MAX) {
+ const int unicode = (xf_graph && isutf8 &&
+ (t_acs_locale_breaks || 0 == (DC_ASCIIONLY & x_display_ctrl)));
+ int uch;
+
+ ED_TRACE3(("graphic(isutf8:%d, char:%d/0x%x)\n", isutf8, c, c))
+ if (unicode && (uch = cmap_specunicode(c)) > 0) {
+ if (CH_PADDING == (c = uch)) {
+ ED_TRACE3(("ttputc_pad(row:%d, col:%d\n", ttrow, ttcol))
+ return;
+ }
+ } else {
+ const char *cp;
+
+ if (NULL != (cp = ttspecchar(c))) {
+ ED_TRACE3(("ttputc_spec(row:%d, col:%d, char:%d/0x%x, cp:%s)\n",\
+ ttrow, ttcol, c, c, cp))
+ if (x_pt.pt_tty_graphicsbox) {
+ term_graphic_enter();
+ }
+ ttpush(cp);
+ goto complete;
+ }
+ ED_TRACE3(("--> no mapping\n"))
+ }
+ }
+
+ /*
+ * width character enabled displays
+ */
+ if (isutf8 && MCHAR_ISUTF8(c)) { /* MCHAR */
+ if ((width = ucs_width(c)) >= 0) {
+ ED_TRACE3(("ttputc_utf8(row:%d, col:%d, char:%d/0x%x, width:%d)\n",\
+ ttrow, ttcol, c, c, width))
+ term_graphic_exit();
+ t_count += charset_utf8_encode(c, (char *)(t_buffer + t_count));
+ goto complete;
+ }
+ width = 1; /* control */
+ }
+ }
+
+ /*
+ * others
+ */
+ ED_TRACE3(("ttputc_norm(row:%d, col:%d, char:%d/0x%x/%c)\n",\
+ ttrow, ttcol, c, c, (c >= 32 && c < 0x7f ? c : '.')))
+
+ term_graphic_exit();
+ if (ASCIIDEF_ESC == c && x_pt.pt_escape[0]) {
+ ttpush(x_pt.pt_escape);
+ goto complete;
+
+ } else if (c >= 0x80) {
+ if (c >= 0xa0 || 0 == x_pt.pt_character[0]) {
+ goto hell;
+ }
+
+ ED_TERM(("ttchar(ch:0x%2x/?, wid:%d, pos:%2d/%2d, cnt:%d)\n",\
+ c, width, ttrow, ttcol, t_count))
+ t_count += sprintf((char *)(t_buffer + t_count), x_pt.pt_character, (int)c);
+ goto complete;
+ }
+
+ if ('~' == c && tf_hz) { /* no hazel support (rare) - remap */
+ c = '^';
+ }
+
+hell:;
+ ED_TERM(("ttchar(ch:0x%2x/%c, attr:0x%2x, wid:%d, pos:%2d/%2d, cnt:%d)\n", \
+ c, (c <= 0x79 ? c : ' '), width, ttrow, ttcol, t_count))
+
+ t_buffer[t_count++] = (unsigned char)(c);
+ assert(c >= ' ');
+
+ if ('\b' == c) { /* backspace */
+ if (ttcol) {
+ ED_TRACE3(("ttmove(%d,%d->back\n", ttrow, ttcol))
+ ttposset(ttrow, ttcol - 1);
+ } else {
+ ttposinvalid();
+ }
+ return;
+
+ } else if ('\n' == c) { /* new-line */
+ if (ttrow < rows) {
+ ED_TRACE3(("ttmove(%d,%d->newline\n", ttrow, ttcol))
+ ttposset(ttrow + 1, ttcol);
+ } else {
+ ttposinvalid();
+ }
+ return;
+
+ } else if ('\r' == c) { /* return */
+ ED_TRACE3(("ttmove(%d,%d->return\n", ttrow, ttcol))
+ ttposset(ttrow, 0);
+ return;
+
+ } else if (ASCIIDEF_BEL == c) { /* bell (noisy) */
+ ED_TRACE3(("ttmove(%d,%d)->bell\n", ttrow, ttcol))
+ return;
+ }
+
+complete:;
+ ttcol += width;
+
+ ED_TRACE3(("ttmove(%d,%d)-", ttrow, ttcol))
+
+ if (ttcol > cols) { /* cursor wrap */
+ /*
+ * Source: http://www.gnu.org/software/termutils/manual/
+ */
+ if (tf_xn && (cols >= 80 || ttrow == rows)) {
+ /*
+ * undefined/strange eol cursor rules/NL ignore after 80th column
+ */
+ ED_TRACE3(("xn-(-1,-1)\n"))
+ ttposinvalid();
+ return;
+
+ } else if (tf_am) {
+ /*
+ * obeys margins
+ */
+ ED_TRACE3(("wrap(%d,%d)", tt_top, tt_bot))
+ if (tt_bot >= 0) {
+ if (++ttrow > tt_bot) {
+ ttrow = tt_bot; /* scroll region active */
+ }
+ } else if (++ttrow > rows) {
+ ttrow = rows; /* otherwise physical screen */
+ }
+ ttcol = 0;
+
+ } else {
+ /*
+ * nowrap/ignored
+ */
+ ED_TRACE3(("->nowrap", ttrow, ttcol))
+ --ttcol;
+ }
+ }
+
+ ED_TRACE3(("-(%d,%d)\n", ttrow, ttcol))
+ ttposset(ttrow, ttcol);
+}
+
+
+/* Function: term_graphic_enter
+ * Switch terminal into graphics/altnative character set mode.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static __CINLINE void
+term_graphic_enter(void)
+{
+ if (xf_graph) {
+ if (FALSE == t_gmode) {
+ const char *cmd = x_pt.pt_graphics_mode;
+
+ if (0 == cmd[0]) {
+ cmd = tc_acs_start; /* default */
+ }
+ if (cmd[0]) {
+ ttputpad(cmd);
+ t_gmode = TRUE;
+ }
+ ED_TRACE3(("term_graphic_enter(%d)\n", t_gmode))
+ }
+ }
+}
+
+
+/* Function: term_graphic_exit
+ * Switch terminal out of graphics/alternative character set mode.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static __CINLINE void
+term_graphic_exit(void)
+{
+ if (t_gmode) {
+ const char *cmd = x_pt.pt_text_mode;
+
+ if (0 == cmd[0]) {
+ cmd = tc_acs_end; /* default */
+ }
+ if (cmd[0]) {
+ ttputpad(cmd);
+ }
+ t_gmode = FALSE;
+ ED_TRACE3(("term_graphic_exit()\n"))
+ }
+}
+
+
+/* Function: term_flush
+ * Flush the tty buffer.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+term_flush(void)
+{
+ if (t_count > sizeof(t_buffer)) {
+ panic("ttbuffer overflow.");
+ }
+
+ if (t_count > 0) {
+ t_charout += t_count;
+ if (FALSE == x_background) {
+ if (!xf_compat) { /* TRUE=normal i/o otherwise optimised */
+ sys_tty_delay(TTY_OUTFD, 1);
+ }
+ ED_TERM(("term_flush(length:%d)\n", t_count))
+#if defined(ED_LEVEL) && (ED_LEVEL >= 1)
+ if (DB_TERMINAL & x_dflags) {
+ trace_data(t_buffer, t_count, "\n");
+ }
+#endif
+ sys_write(TTY_OUTFD, t_buffer, t_count);
+ }
+ t_count = 0;
+ }
+}
+
+
+/* Function: term_sizeget
+ * Retrieve the display screen.
+ *
+ * Parameters:
+ * nrow - Storage for row number.
+ * ncol - Number of columns.
+ *
+ * Returns:
+ * void
+ */
+static void
+term_sizeget(int *nrow, int *ncol)
+{
+ const char *env;
+#if defined(TIOCGWINSZ)
+ struct winsize ws = {0};
+
+ do {
+ if ((ioctl(1, TIOCGWINSZ, (char *) &ws) == 0) ||
+ (ioctl(0, TIOCGWINSZ, (char *) &ws) == 0) ||
+ (ioctl(2, TIOCGWINSZ, (char *) &ws) == 0)) {
+ if (ws.ws_row > 0 && ws.ws_col > 0) {
+ *nrow = ws.ws_row;
+ *ncol = ws.ws_col;
+ trace_ilog("term_size1(%d, %d)\n", *nrow, *ncol);
+ return;
+ }
+ }
+ } while (errno == EINTR);
+
+#elif defined(TIOCGSIZE)
+ struct ttysize ts = {0}; /* SUN */
+
+ do {
+ if ((ioctl(1, TIOCGSIZE, (char *) &ts) == 0) ||
+ (ioctl(0, TIOCGSIZE, (char *) &ts) == 0) ||
+ (ioctl(2, TIOCGSIZE, (char *) &ts) == 0)) {
+ if (ts.ts_lines > 0 && ts.ts_linesncol > 0) {
+ *nrow = ts.ts_lines;
+ *ncol = ts.ts_cols;
+ trace_ilog("term_size2(%d, %d)\n", *nrow, *ncol);
+ return;
+ }
+ }
+ } while (errno == EINTR);
+#endif
+
+#if defined(_VMS)
+ { /* UNTESTED/OLD */
+ unsigned short chan;
+
+ $DESCRIPTOR(dev_dsc, "SYS$INPUT:");
+ if (sys$assign(&dev_dsc, &chan, 0, 0, 0) & 1) {
+ int status_col, status_row, code;
+
+ code = DVI$_DEVBUFSIZ;
+ status_col = lib$getdvi(&code, &chan, 0, ncol, 0, 0);
+ code = DVI$_TT_PAGE;
+ status_row = lib$getdvi(&code, &chan, 0, nrow, 0, 0);
+ sys$dassgn(chan);
+ if ((status_col & 1) && (status_row & 1)) {
+ return;
+ }
+ }
+ }
+#endif
+
+ if (tn_li > 0 && tn_co > 0) { /* terminal */
+ *nrow = tn_li;
+ *ncol = tn_co;
+ } else {
+ *nrow = 24;
+ *ncol = 80;
+ }
+ /* old school */
+ if (NULL != (env = ggetenv("LINES")) && *env) {
+ *nrow = atoi(env);
+ tf_am = FALSE;
+ }
+
+ if (NULL != (env = ggetenv("COLUMNS")) && *env) {
+ *ncol = atoi(env);
+ tf_am = FALSE;
+ }
+}
+
+
+#if (NOTUSED)
+/* Function: term_sizeset
+ * Attempt to set the current window size.
+ *
+ * Parameters:
+ * row - Screen rows.
+ * col - Columns.
+ *
+ * Returns:
+ * On success 0, otherwise -1.
+ */
+static int
+term_sizeset(int rows, int cols)
+{
+ if (x_pt.pt_winsetsize[0]) {
+ ttprintf(x_pt.pt_winsetsize, rows, cols);
+ return 0;
+ }
+ return -1;
+}
+#endif
+
+
+/* Function: ega_switch
+ * EGA/VGA console mode switch support
+ *
+ * Parameters:
+ * flag - EGA mode.
+ *
+ * Returns:
+ * nothing.
+ */
+static void
+ega_switch(int flag)
+{
+ const int orows = ttrows();
+
+ if (tty_egaflag == flag) {
+ return;
+ }
+
+ switch (flag) {
+#if defined(SW_VGA_C80x60)
+ case 60: /* 60 line mode */
+ ioctl(1, SW_VGA_C80x60, 1);
+ ttrows() = 60;
+ break;
+#endif
+
+#if defined(SW_VGA_C80x50)
+ case 50: /* 50 line mode */
+ ioctl(1, SW_VGA_C80x50, 1);
+ ttrows() = 50;
+ break;
+#endif
+
+#if defined(SW_ENH_C80x43)
+ case 43: /* 43 line mode */
+ if (ioctl(1, SW_ENH_C80x43, 1) == 0) {
+ ttrows() = 43;
+ }
+ break;
+#endif
+
+#if defined(SW_VGA_C80x25) || defined(SW_ENH_C80x25)
+ case 25: /* 25 line mode */
+#if defined(SW_VGA_C80x25)
+ ioctl(1, SW_VGA_C80x25, 1);
+#endif
+#if defined(SW_ENH_C80x25)
+ ioctl(1, SW_ENH_C80x25, 1);
+#endif
+ ttrows() = 25;
+ break
+#endif
+
+ default:
+ acc_assign_int(-1);
+ return;
+ }
+
+ tty_egaflag = xf_ega43 = flag;
+ vtwinch(ttcols(), orows);
+ term_colorreset();
+}
+
+
+/* Function: do_ega
+ * ega primitive.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ *
+ *<>
+ Macro: ega - Terminal line display.
+
+ int
+ ega(int lines)
+
+ Macro Description:
+ The 'ega()' primitive attempts to configure the console size
+ to the specified number of 'lines' with an implied width of
+ 80 columns on supporting terminals.
+
+ Possible screen dimensions include.
+
+ o 60 x 80
+ o 50 x 80
+ o 43 x 80
+ o 25 x 80
+
+ Macro Parameters:
+ lines - Optional integer specifing the required number of
+ console lines. Under WIN32 if -1 the console size shall toggled
+ bewteen minimized and maximised. If omitted, then only the
+ current state is returned.
+
+ Notes!:
+ When running within a windows console, before Windows 7 one could press
+ to run the application in full screen. As of Windows 7 this
+ functionality is no longer available resulting in the following.
+
+> This system does not support full screen mode
+
+ The ega() primitive can be used to emulate this functionality, using
+ the special -1 flag, which shall toggle between a minimized or maximised
+ sized console.
+
+> ega(-1)
+
+ Macro Returns:
+ The 'ega()' primitive returns the previous status, otherwise -1 upon
+ an error.
+
+ Macro Portability:
+ A Grief extension.
+
+ Macro See Also:
+ set_term_feature
+ */
+void
+do_ega(void) /* int (int mode) */
+{
+ acc_assign_int((accint_t) xf_ega43);
+ if (isa_integer(1)) { /* (mode < 80 sets rows), otherwise (mode >= 80 sets columns). */
+ const int flag = get_xinteger(1, 0);
+ if (flag >= 0) {
+ ega_switch(flag);
+ }
+ }
+}
+
+
+/* Function: do_copy_screen
+ * copy_screen primitive, defunct.
+ *
+ * Parameters:
+ * none.
+ *
+ * Returns:
+ * nothing.
+ *
+ *<>
+ Macro: copy_screen - Copy the current screen.
+
+ void
+ copy_screen()
+
+ Macro Description:
+ The 'copy_screen()' primitive exports an image of the
+ current editor windows to the current buffer.
+
+ Macro Parameters:
+ none
+
+ Macro Returns:
+ nothing
+
+ Macro Portability:
+ A Grief extension; this primitive is subject for removal,
+ and has been removed from recent CrispEdit(tm) releases.
+
+ Macro See Also:
+ transfer
+ */
+void
+do_copy_screen(void) /* void () */
+{
+}
+
+#endif /*!USE_VIO_BUFFER && !DJGPP */
diff --git a/gr/ttyvio.c b/gr/ttyvio.c
index a3500d5a..2b416ddd 100644
--- a/gr/ttyvio.c
+++ b/gr/ttyvio.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_ttyvio_c,"$Id: ttyvio.c,v 1.68 2020/05/03 18:24:42 cvsuser Exp $")
+__CIDENT_RCSID(gr_ttyvio_c,"$Id: ttyvio.c,v 1.72 2021/07/05 15:01:27 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: ttyvio.c,v 1.68 2020/05/03 18:24:42 cvsuser Exp $
+/* $Id: ttyvio.c,v 1.72 2021/07/05 15:01:27 cvsuser Exp $
* TTY VIO implementation.
*
*
@@ -25,6 +25,8 @@ __CIDENT_RCSID(gr_ttyvio_c,"$Id: ttyvio.c,v 1.68 2020/05/03 18:24:42 cvsuser Exp
#include
#include /* gputenvv(), ggetenv() */
#include
+#include "../libchartable/libchartable.h"
+#include "../libwidechar/widechar.h"
#if defined(WIN32)
#ifndef _WIN32_WINNT
@@ -403,8 +405,11 @@ term_feature(int ident, scrprofile_t *profile)
break;
case TF_ENCODING:
+ break;
case TF_UNICODE_VERSION:
- case TF_UNICODE_WIDTH:
+ if (x_pt.pt_unicode_version[0]) {
+ ucs_width_set(x_pt.pt_unicode_version);
+ }
break;
}
}
@@ -806,8 +811,10 @@ term_font(int setlen, char *font)
static void
term_print(int row, int col, int len, const VCELL_t *vvp)
{
+ static VIOCELL null = { 0 };
+
if (len > 0) {
- const int isuc = (DC_CMAPFRAME & x_display_ctrl) || vtisutf8() || vtisunicode();
+ const int isuc = (DC_CMAPFRAME & x_display_ctrl) || vtisunicode() || vtisutf8();
VIOCELL *p = currScreen + (row * ttcols()) + col;
vbyte_t cattr = VBYTE_ATTR_GET(vvp->primary);
@@ -817,6 +824,12 @@ term_print(int row, int col, int len, const VCELL_t *vvp)
const vbyte_t attr = VBYTE_ATTR_GET(vvp->primary);
vbyte_t c = VBYTE_CHAR_GET(vvp->primary);
+ if (CH_PADDING == c) { /* wide character padding */
+ *p++ = null;
+ ++vvp;
+ continue;
+ }
+
if (cattr != attr) { /* attribute change */
cattr = attr, term_attribute(cattr);
}
@@ -844,7 +857,7 @@ term_print(int row, int col, int len, const VCELL_t *vvp)
/* Function: term_putc
- * Write character to the display.
+ * Write character to the display. Generally unsed, as term_print() has priority.
*
* Parameters:
* c - Character value.
@@ -857,6 +870,10 @@ term_putc(vbyte_t c)
{
int ttrow = ttatrow(), ttcol = ttatcol();
+ if (CH_PADDING == c) { /* wide character padding */
+ return;
+ }
+
term_attribute(VBYTE_ATTR_GET(c));
c = VBYTE_CHAR_GET(c);
@@ -864,7 +881,7 @@ term_putc(vbyte_t c)
* special characters
*/
if (c >= CH_MIN && c <= CH_MAX) {
- const int isuc = (DC_CMAPFRAME & x_display_ctrl) || vtisutf8() || vtisunicode();
+ const int isuc = (DC_CMAPFRAME & x_display_ctrl) || vtisunicode() || vtisutf8();
int unicode;
if (isuc && (unicode = cmap_specunicode(c)) > 0) {
diff --git a/gr/ttywin32.c b/gr/ttywin32.c
index 10eb3985..661369c6 100644
--- a/gr/ttywin32.c
+++ b/gr/ttywin32.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_ttywin32_c,"$Id: ttywin32.c,v 1.50 2020/05/03 18:57:00 cvsuser Exp $")
+__CIDENT_RCSID(gr_ttywin32_c,"$Id: ttywin32.c,v 1.52 2021/07/11 08:24:15 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: ttywin32.c,v 1.50 2020/05/03 18:57:00 cvsuser Exp $
+/* $Id: ttywin32.c,v 1.52 2021/07/11 08:24:15 cvsuser Exp $
* WIN32 VIO driver.
* see: http://www.edm2.com/index.php/Category:Vio
*
@@ -49,8 +49,6 @@ __CIDENT_RCSID(gr_ttywin32_c,"$Id: ttywin32.c,v 1.50 2020/05/03 18:57:00 cvsuser
#define TERMEMU_VIO_STATIC /* private interface */
#include "termemu_vio.c"
-#include "unicode_cp437.h"
-
static void VioInitialise(void);
static void VioEncoding(void);
@@ -976,4 +974,4 @@ DosBeep(int freq, int duration)
#endif // USE_VIO_BUFFER
#endif // WIN32
-/*end*/
\ No newline at end of file
+/*end*/
diff --git a/gr/ttyx11kb.h b/gr/ttyx11kb.h
index 7ac1aada..17a64bdb 100644
--- a/gr/ttyx11kb.h
+++ b/gr/ttyx11kb.h
@@ -1,11 +1,11 @@
#ifndef GR_TTYX11KB_H_INCLUDED
#define GR_TTYX11KB_H_INCLUDED
#include
-__CIDENT_RCSID(gr_ttyx11kb_h,"$Id: ttyx11kb.h,v 1.4 2014/10/22 02:33:24 ayoung Exp $")
+__CIDENT_RCSID(gr_ttyx11kb_h,"$Id: ttyx11kb.h,v 1.5 2021/07/18 23:03:19 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: ttyx11kb.h,v 1.4 2014/10/22 02:33:24 ayoung Exp $
+/* $Id: ttyx11kb.h,v 1.5 2021/07/18 23:03:19 cvsuser Exp $
* X11 keyboard translation tables.
*
* These tables direct the translation of X keyboard events into our internal
@@ -90,7 +90,7 @@ static const KeyboardXlat plainXlatSeed[] = {
{ XK_Find, KEY_SEARCH },
{ XK_Cancel, KEY_CANCEL },
{ XK_Help, KEY_HELP },
- { XK_Break, KEY_VOID },
+ { XK_Break, KEY_BREAK },
{ XK_Mode_switch, KEY_VOID },
{ XK_script_switch, KEY_VOID },
{ XK_Num_Lock, KEY_VOID },
diff --git a/gr/undo.c b/gr/undo.c
index a3229065..f0fa0a16 100644
--- a/gr/undo.c
+++ b/gr/undo.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_undo_c,"$Id: undo.c,v 1.49 2021/04/14 14:09:54 cvsuser Exp $")
+__CIDENT_RCSID(gr_undo_c,"$Id: undo.c,v 1.50 2021/06/10 06:13:02 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: undo.c,v 1.49 2021/04/14 14:09:54 cvsuser Exp $
+/* $Id: undo.c,v 1.50 2021/06/10 06:13:02 cvsuser Exp $
* undo and redo facilities.
*
*
@@ -215,7 +215,7 @@ undo_close(void)
if (u_fp) {
fclose(u_fp);
if (u_fname[0]) {
- fileio_unlink(u_fname);
+ sys_unlink(u_fname);
}
u_fname[0] = 0;
u_fp = NULL;
@@ -289,7 +289,7 @@ u_insert(FSIZE_t length, int dot)
undo.u_length = n;
uwrite_op(&undo);
- lp = vm_lock_line(cline);
+ lp = vm_lock_line2(cline);
while (n > 0 && cline <= numlines) { /* NEWLINE */
FSIZE_t x, w;
diff --git a/gr/version.c b/gr/version.c
index f75b5fd5..9a18bdbd 100644
--- a/gr/version.c
+++ b/gr/version.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_version_c,"$Id: version.c,v 1.27 2020/05/03 21:41:54 cvsuser Exp $")
+__CIDENT_RCSID(gr_version_c,"$Id: version.c,v 1.28 2021/04/20 13:59:56 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: version.c,v 1.27 2020/05/03 21:41:54 cvsuser Exp $
+/* $Id: version.c,v 1.28 2021/04/20 13:59:56 cvsuser Exp $
* Version strings.
*
*
@@ -26,6 +26,6 @@ const int x_edit_version = GR_VERSION_3;
const char * x_version = GR_VERSION;
const char * x_compiled = __DATE__ " " __TIME__;
-const char * x_copyright = "(C) 1998-2020 A. Young, 1991 P. Fox";
+const char * x_copyright = "(C) 1998-2021 A. Young, 1991 P. Fox";
/*end*/
diff --git a/gr/widgets_tty.c b/gr/widgets_tty.c
index 3060ba81..c1abfa28 100644
--- a/gr/widgets_tty.c
+++ b/gr/widgets_tty.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_widgets_tty_c,"$Id: widgets_tty.c,v 1.35 2020/04/19 23:55:19 cvsuser Exp $")
+__CIDENT_RCSID(gr_widgets_tty_c,"$Id: widgets_tty.c,v 1.37 2021/08/01 14:42:51 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: widgets_tty.c,v 1.35 2020/04/19 23:55:19 cvsuser Exp $
+/* $Id: widgets_tty.c,v 1.37 2021/08/01 14:42:51 cvsuser Exp $
* Dialog widgets, tty interface.
*
*
@@ -32,7 +32,9 @@ __CIDENT_RCSID(gr_widgets_tty_c,"$Id: widgets_tty.c,v 1.35 2020/04/19 23:55:19 c
#include "kill.h"
#include "line.h"
#include "lisp.h"
+#include "mchar.h"
#include "main.h"
+
#include "tty.h"
#include "widgets.h"
#include "widgets_tty.h"
@@ -285,15 +287,16 @@ tty_str(LINEATTR attr, const char *str)
* ch -
*
* Returns:
- * nothing.
+ * int - Character display width.
*/
-static void
+static int
tty_char(LINEATTR attr, int ch)
{
const LINEATTR oattr = *cur_attr;
*cur_attr = attr;
lwritec(ch);
*cur_attr = oattr;
+ return Wcwidth(ch);
}
@@ -302,7 +305,8 @@ tty_isunicode(int special)
{
__CUNUSED(special)
#if defined(WIN32) || defined(__CYGWIN__)
- if (special) return FALSE; /* generally aren't available */
+ if (special) /* FIXME; generally aren't available. */
+ return FALSE;
#endif
return (DC_UNICODE == ((DC_UNICODE|DC_ASCIIONLY) & x_display_ctrl));
}
@@ -2926,6 +2930,7 @@ lb_paint(Listbox_t *lb, WIDGET_t *w, int repaint)
}
}
+ move(w, 1, frame + y); /* left align */
++y, ++idx;
}
}
@@ -3033,9 +3038,17 @@ typedef struct {
int ef_length; /* buffer length, in bytes */
const char * ef_placeholder; /* placeholder text, if any */
- char ef_buffer[ MAX_CMDLINE ];
+
+#define EWIDECHAR
+#if defined(EWIDECHAR)
+#define ECHAR WChar_t
+ char ef_xbuffer[ MAX_CMDLINE ];
+#else
+#define ECHAR char
+#endif
+ ECHAR ef_buffer[ MAX_CMDLINE ];
+ ECHAR ef_restore[ MAX_CMDLINE ];
char ef_complete[ MAX_CMDLINE ];
- char ef_restore[ MAX_CMDLINE ];
} Editfield_t;
static void ef_init(Editfield_t *ef, uint32_t flags);
@@ -3045,6 +3058,8 @@ static void ef_destroy(Editfield_t *ef);
static void ef_save(Editfield_t *ef);
static void ef_restore(Editfield_t *ef);
static void ef_set(Editfield_t *ef, const char *value);
+static const char * ef_get(Editfield_t *ef);
+static int ef_empty(const Editfield_t *ef);
static int ef_assign(Editfield_t *ef, const WIDGETDATA_t *data);
static int ef_value_set(Editfield_t *ef, const WIDGETARG_t p1, const WIDGETDATA_t *data);
static int ef_value_get(Editfield_t *ef, const WIDGETARG_t p1, WIDGETDATA_t *data);
@@ -3067,7 +3082,7 @@ ef_init(Editfield_t *ef, uint32_t flags)
ef->ef_changed = 0;
ef->ef_format = EDITFORMAT_TEXT;
ef->ef_seqno = 0;
- ef->ef_length = sizeof(ef->ef_buffer) - 1;
+ ef->ef_length = _countof(ef->ef_buffer)-1;
ef->ef_editable = TRUE;
ef->ef_visibility = TRUE;
ef->ef_validate = FALSE;
@@ -3079,6 +3094,9 @@ ef_init(Editfield_t *ef, uint32_t flags)
ef->ef_filters = 0;
ef->ef_placeholder = NULL;
ef->ef_buffer[0] = 0;
+#if defined(EWIDECHAR)
+ ef->ef_xbuffer[0] = 0;
+#endif
ef->ef_complete[0] = 0;
ef->ef_restore[0] = 0;
ef->ef_restoreseqno = 0;
@@ -3129,17 +3147,22 @@ ef_destroy(Editfield_t *ef)
static void
ef_save(Editfield_t *ef)
{
- const int diff = strcmp(ef->ef_buffer, ef->ef_restore);
+ const ECHAR *buffer = ef->ef_buffer;
+#if defined(EWIDECHAR)
+ const int diff = Wcscmp(buffer, ef->ef_restore);
+ Wcscpy(ef->ef_restore, buffer);
+#else
+ const int diff = strcmp(buffer, ef->ef_restore);
+ strcpy(ef->ef_restore, buffer);
+#endif
- strcpy(ef->ef_restore, (const char *)ef->ef_buffer);
ef->ef_restoreseqno = ef->ef_seqno;
-
if (diff) ++ef->ef_seqno;
ef->ef_quote = FALSE;
ef->ef_cursor = 0;
ef->ef_loffset = 0;
ef->ef_marked =
- (((EF_FISAUTOCOMPLETE & ef->ef_flags) || 1 == ef->ef_seqno) && ef->ef_buffer[0] ? TRUE : FALSE);
+ (((EF_FISAUTOCOMPLETE & ef->ef_flags) || 1 == ef->ef_seqno) && buffer[0] ? TRUE : FALSE);
ef->ef_append = FALSE;
ef->ef_changed = 0;
ef->ef_complete[0] = 0;
@@ -3149,7 +3172,8 @@ ef_save(Editfield_t *ef)
static void
ef_restore(Editfield_t *ef)
{
- strcpy(ef->ef_buffer, (const char *)ef->ef_restore);
+ assert(sizeof(ef->ef_buffer) == sizeof(ef->ef_restore));
+ memcpy(ef->ef_buffer, (const void *)ef->ef_restore, sizeof(ef->ef_buffer));
ef->ef_seqno = ef->ef_restoreseqno;
ef->ef_quote = FALSE;
ef->ef_changed = 0;
@@ -3164,12 +3188,38 @@ ef_set(Editfield_t *ef, const char *value)
ef->ef_quote = FALSE;
ef->ef_marked = FALSE;
ef->ef_append = FALSE;
+#if defined(EWIDECHAR)
+ Wcsfromutf8((value ? value : ""), ef->ef_buffer, _countof(ef->ef_buffer));
+#else
strxcpy(ef->ef_buffer, (value ? value : ""), sizeof(ef->ef_buffer));
+#endif
ef->ef_complete[0] = 0;
++ef->ef_changed;
}
+static const char *
+ef_get(Editfield_t *ef)
+{
+#if defined(EWIDECHAR)
+ ef->ef_xbuffer[0] = 0;
+ if (ef->ef_buffer[0]) {
+ Wcstoutf8(ef->ef_buffer, ef->ef_xbuffer, sizeof(ef->ef_xbuffer));
+ }
+ return ef->ef_xbuffer;
+#else
+ return ef->ef_buffer;
+#endif
+}
+
+
+static int
+ef_empty(const Editfield_t *ef)
+{
+ return (*ef->ef_buffer == 0);
+}
+
+
static int
ef_assign(Editfield_t *ef, const WIDGETDATA_t *data)
{
@@ -3266,7 +3316,7 @@ ef_value_get(Editfield_t *ef, const WIDGETARG_t p1, WIDGETDATA_t *data)
switch (attr) {
case DLGA_VALUE:
- data->d_u.svalue = ef->ef_buffer;
+ data->d_u.svalue = ef_get(ef);
data->d_type = D_STR;
return TRUE;
case DLGA_EDEDITABLE:
@@ -3376,13 +3426,18 @@ ef_value_get(Editfield_t *ef, const WIDGETARG_t p1, WIDGETDATA_t *data)
static int
ef_key(Editfield_t *ef, WIDGET_t *w, int key, int (*validate)(Editfield_t *, WIDGET_t *w, void *), void *arg)
{
- char previous_buffer[ MAX_CMDLINE ];
- int oipos = ef->ef_cursor, ipos = oipos;
- char *buf = ef->ef_buffer;
- int repaint = FALSE;
- int edit = FALSE;
-
+ ECHAR previous_buffer[ MAX_CMDLINE ];
+ ECHAR *buf = ef->ef_buffer;
+ int oipos = ef->ef_cursor, ipos = oipos;
+ int repaint = FALSE;
+ int edit = FALSE;
+
+#if defined(EWIDECHAR)
+ Wcsncpy(previous_buffer, (const WChar_t *)buf, _countof(previous_buffer));
+#else
strxcpy(previous_buffer, (const char *)buf, sizeof(previous_buffer));
+#endif
+
if (ef->ef_quote) {
ef->ef_quote = FALSE;
goto quote;
@@ -3431,22 +3486,38 @@ ef_key(Editfield_t *ef, WIDGET_t *w, int key, int (*validate)(Editfield_t *, WID
if (ef->ef_marked) {
repaint = TRUE, ef->ef_marked = 0;
}
+#if defined(EWIDECHAR)
+ ipos = (int)Wcslen(buf);
+#else
ipos = (int)strlen(buf);
+#endif
break;
case KEY_WLEFT: /* Cursor word left/decrement */
case KEY_WLEFT2: {
double val = 0;
if (EF_FISNUMERIC & ef->ef_flags) {
-decrement:; if (*ef->ef_buffer) {
- val = atof(ef->ef_buffer);
+decrement:; if (*buf) {
+#if defined(EWIDECHAR)
+ val = Wcstod(buf, NULL);
+#else
+ val = atof(buf);
+#endif
}
val -= ef->ef_increment;
+#if defined(EWIDECHAR)
+ if (ef->ef_digits <= 0) {
+ ipos = Wsnprintf(buf, _countof(ef->ef_buffer), "%d", (int) val);
+ } else {
+ ipos = Wsnprintf(buf, _countof(ef->ef_buffer), "%*f", ef->ef_digits, val);
+ }
+#else
if (ef->ef_digits <= 0) {
- ipos = sprintf(ef->ef_buffer, "%d", (int) val);
+ ipos = sprintf(buf, "%d", (int) val);
} else {
- ipos = sprintf(ef->ef_buffer, "%*f", ef->ef_digits, val);
+ ipos = sprintf(buf, "%*f", ef->ef_digits, val);
}
+#endif
edit = TRUE;
} else {
while (isspace(buf[ipos]) && ipos > 0) {
@@ -3463,15 +3534,27 @@ decrement:; if (*ef->ef_buffer) {
case KEY_WRIGHT2: {
double val = 0;
if (EF_FISNUMERIC & ef->ef_flags) {
-increment:; if (*ef->ef_buffer) {
- val = atof(ef->ef_buffer);
+increment:; if (*buf) {
+#if defined(EWIDECHAR)
+ val = Wcstod(buf, NULL);
+#else
+ val = atof(buf);
+#endif
}
val += ef->ef_increment;
+#if defined(EWIDECHAR)
+ if (ef->ef_digits <= 0) {
+ ipos = Wsnprintf(buf, _countof(ef->ef_buffer), "%d", (int) val);
+ } else {
+ ipos = Wsnprintf(buf, _countof(ef->ef_buffer), "%*f", ef->ef_digits, val);
+ }
+#else
if (ef->ef_digits <= 0) {
- ipos = sprintf(ef->ef_buffer, "%d", (int) val);
+ ipos = sprintf(buf, "%d", (int) val);
} else {
- ipos = sprintf(ef->ef_buffer, "%*f", ef->ef_digits, val);
+ ipos = sprintf(buf, "%*f", ef->ef_digits, val);
}
+#endif
edit = TRUE;
} else {
while (isspace(buf[ipos]) && buf[ipos]) {
@@ -3490,24 +3573,34 @@ increment:; if (*ef->ef_buffer) {
repaint = TRUE, ef->ef_marked = 0;
}
if (ipos > 0) {
- --ipos, strcpy(buf + ipos, buf + ipos + 1);
+ --ipos;
+#if defined(EWIDECHAR)
+ Wcscpy(buf + ipos, buf + ipos + 1);
+#else
+ strcpy(buf + ipos, buf + ipos + 1);
+#endif
edit = TRUE;
}
}
break;
case KEY_DEL: /* delete character under the cursor */
- case 0x7F:
+ case KEY_DELETE:
case CTRL_D:
if (ef->ef_editable) {
if (ef->ef_marked) {
- edit = TRUE, ef->ef_marked = 0;
+ ef->ef_marked = 0;
memset(ef->ef_complete, 0, sizeof(ef->ef_complete));
- memset(buf, 0, ef->ef_length);
+ memset(buf, 0, sizeof(ef->ef_buffer));
+ edit = TRUE;
ipos = 0;
} else if (buf[ipos]) {
+#if defined(EWIDECHAR)
+ Wcscpy(buf + ipos, buf + ipos + 1);
+#else
strcpy(buf + ipos, buf + ipos + 1);
+#endif
edit = TRUE;
}
}
@@ -3525,9 +3618,9 @@ increment:; if (*ef->ef_buffer) {
case CTRL_X:
case CTRL_U:
if (ef->ef_editable) {
- ipos = 0;
buf[0] = '\0';
edit = TRUE;
+ ipos = 0;
}
break;
@@ -3545,7 +3638,11 @@ increment:; if (*ef->ef_buffer) {
} else {
while (ipos < ef->ef_length && scount--) {
if (ef->ef_insmode) {
+#if defined(EWIDECHAR)
+ Wmemmove(buf + ipos + 1, (const WChar_t *)(buf + ipos), (size_t)ef->ef_length - ipos);
+#else
memmove(buf + ipos + 1, (const char *)(buf + ipos), (size_t)ef->ef_length - ipos);
+#endif
}
if (0 == buf[ ipos ]) {
buf[ ipos+1 ] = '\0';
@@ -3595,7 +3692,11 @@ increment:; if (*ef->ef_buffer) {
goto decrement;
} else if ('.' == key) {
- if (ef->ef_digits <= 0 || strchr(ef->ef_buffer, '.')) {
+#if defined(EWIDECHAR)
+ if (ef->ef_digits <= 0 || Wcschr(buf, '.')) {
+#else
+ if (ef->ef_digits <= 0 || strchr(buf, '.')) {
+#endif
return FALSE;
}
@@ -3609,8 +3710,13 @@ increment:; if (*ef->ef_buffer) {
}
}
-quote:; if (ef->ef_marked) { /* zap marked text */
+ quote:;
+ if (ef->ef_marked) { /* zap marked text */
+#if defined(EWIDECHAR)
+ Wmemset(buf, 0, ef->ef_length);
+#else
memset(buf, 0, ef->ef_length);
+#endif
ef->ef_marked = 0;
edit = TRUE;
ipos = 0;
@@ -3620,7 +3726,11 @@ quote:; if (ef->ef_marked) { /* zap marked text */
ttbeep(); /* end-of-buffer */
} else {
if (ef->ef_insmode) { /* insert mode */
+#if defined(EWIDECHAR)
+ Wmemmove(buf + ipos + 1, (const WChar_t *)(buf + ipos), (size_t)ef->ef_length - ipos);
+#else
memmove(buf + ipos + 1, (const char *)(buf + ipos), (size_t)ef->ef_length - ipos);
+#endif
}
if (0 == buf[ ipos ]) { /* make sure buffer is terminated */
buf[ ipos+1 ] = '\0';
@@ -3636,13 +3746,22 @@ quote:; if (ef->ef_marked) { /* zap marked text */
++ef->ef_changed;
if (validate) {
if (! validate(ef, w, arg)) { /* reject, restore previous value */
- strxcpy(ef->ef_buffer, (const char *)previous_buffer, sizeof(ef->ef_buffer));
+#if defined(EWIDECHAR)
+ Wcsncpy(buf, (const WChar_t *)previous_buffer, _countof(ef->ef_buffer));
+#else
+ strxcpy(buf, (const char *)previous_buffer, sizeof(ef->ef_buffer));
+#endif
--ef->ef_changed;
ef->ef_cursor = oipos;
edit = FALSE;
} else {
if (ef->ef_complete[0]) { /* auto-complete, trim cursor */
- if ((ipos = (int)strlen(ef->ef_buffer)) < ef->ef_cursor) {
+#if defined(EWIDECHAR)
+ ipos = (int)Wcslen(buf);
+#else
+ ipos = (int)strlen(buf);
+#endif
+ if (ipos < ef->ef_cursor) {
ef->ef_cursor = ipos;
}
}
@@ -3672,12 +3791,16 @@ ef_paint(Editfield_t *ef, WIDGET_t *w)
const int32_t cols =
(EF_FISCOMBO & ef->ef_flags ? (w->w_cols > 3 ? w->w_cols - 3 : 1) :
(EF_FISNUMERIC & ef->ef_flags ? (w->w_cols > 4 ? w->w_cols - 4 : 1) : w->w_cols));
- const char *complete = (ef->ef_append ? ef->ef_complete : "");
- const char *buffer = (!HasFocus(w) && ef->ef_placeholder && !*ef->ef_buffer && !*complete ?
- ef->ef_placeholder : ef->ef_buffer);
- int32_t len2 = (int32_t)strlen(complete);
- int32_t len = (int32_t)strlen(buffer);
+ const char *complete = (ef->ef_append ? ef->ef_complete : "");
+ const int placeholder = (!HasFocus(w) && ef->ef_placeholder && ef_empty(ef) && !*complete ? 1 : 0);
+
+ int32_t len2 = (int32_t)strlen(complete);
+#if defined(EWIDECHAR)
+ int32_t len = (int32_t)(placeholder ? strlen(ef->ef_placeholder) : Wcslen(ef->ef_buffer));
+#else
+ int32_t len = (int32_t)(placeholder ? strlen(ef->ef_placeholder) : strlen(ef->ef_buffer));
+#endif
int32_t offset = ef->ef_loffset;
int32_t cursor = 0;
@@ -3692,25 +3815,33 @@ ef_paint(Editfield_t *ef, WIDGET_t *w)
len = cols;
}
- buffer += offset;
- if (ef->ef_visibility || /* normal/visible mode/placeholder-text */
- (buffer == ef->ef_placeholder)) {
+ if (placeholder) { /* placeholder text */
+ const char *buffer = ef->ef_placeholder + offset;
+
tty_move(w, 0, 0);
tty_strn(attr, buffer, len);
cursor += len;
+ } else if (ef->ef_visibility) { /* normal/visible mode text */
+ const ECHAR *buffer = ef->ef_buffer + offset;
+
+ while (len-- > 0) {
+ tty_move(w, cursor, 0);
+ cursor += tty_char(attr, *buffer++);
+ }
+
} else { /* invisible, only show previous character when focused */
const int vcharacter = ef->ef_invisiblech;
if (vcharacter > 0) { /* 0=hidden text (ie. no user feeback) */
+ const ECHAR *buffer = ef->ef_buffer + offset;
const int vpos =
(HasFocus(w) && ef->ef_changed ? (ef->ef_cursor - offset) - 1 : -1);
while (len-- > 0) {
tty_move(w, cursor, 0); /* only if last changed character */
- tty_char(attr, 0 == len && vpos == cursor ? *buffer : vcharacter);
+ cursor += tty_char(attr, 0 == len && vpos == cursor ? *buffer : vcharacter);
++buffer;
- ++cursor;
}
}
}
@@ -4282,7 +4413,7 @@ combofield_open(WCombofield_t *cf)
Listbox_t *lb = &cf->cf_listimpl;
int32_t idx = -1;
/* prime active and cursor */
- idx = lb_active(lb, lb_item_match(lb, NULL, ef->ef_buffer, &idx) ? idx : -1);
+ idx = lb_active(lb, lb_item_match(lb, NULL, ef_get(ef), &idx) ? idx : -1);
lb_cursor(lb, w, idx);
ef_save(ef); /* open and save edit buffer */
@@ -4394,7 +4525,7 @@ combofield_autocomplete(Editfield_t *ef, WIDGET_t *w, void *arg)
{
WCombofield_t *cf = (WCombofield_t *)arg;
Listbox_t *lb = &cf->cf_listimpl;
- char *buffer = ef->ef_buffer;
+ const char *buffer = ef_get(ef);
char *complete = ef->ef_complete;
const ListboxItem_t *n = NULL;
int32_t idx = 0;
@@ -4407,14 +4538,18 @@ combofield_autocomplete(Editfield_t *ef, WIDGET_t *w, void *arg)
n = lb_item_find(lb, "", 0, &idx);
/* element index */
} else if ((LB_FINDEXMODE & lb->lb_flags) && isdigit(*buffer)) {
+ char t_buffer[32];
int value;
if ((value = strtol(buffer, NULL, 10)) < 1 || value > (int)lb_item_count(lb) ||
NULL == (n = lb_item_get(lb, idx = (uint32_t)(value - 1)))) {
return FALSE;
}
+
lb_filter(lb, 0, NULL);
- sxprintf(buffer, sizeof(ef->ef_buffer), "%d", value);
+ sxprintf(t_buffer, sizeof(t_buffer), "%d", value);
+ ef_set(ef, t_buffer);
+
strxcpy(complete + 1, n->li_display, sizeof(ef->ef_complete) - 1);
complete[0] = '-';
@@ -4488,15 +4623,15 @@ combofield_listbox(WCombofield_t *cf, const int state)
switch (state) {
// case CB_POPUPSTATE_HIDDEN:
-// switch (current_state) {
-// case CB_POPUPSTATE_FOCUS:
-// case CB_POPUPSTATE_VISIBLE:
-// if (dialog_tty_popup_focus(w->w_root, -1)) {
-// cf->cf_popupstate = CB_POPUPSTATE_HIDDEN;
-// }
-// break;
-// }
-// break;
+// switch (current_state) {
+// case CB_POPUPSTATE_FOCUS:
+// case CB_POPUPSTATE_VISIBLE:
+// if (dialog_tty_popup_focus(w->w_root, -1)) {
+// cf->cf_popupstate = CB_POPUPSTATE_HIDDEN;
+// }
+// break;
+// }
+// break;
case CB_POPUPSTATE_VISIBLE:
switch (current_state) {
@@ -4546,13 +4681,13 @@ combofield_value_get(WCombofield_t *cf, int iscomplete)
{
Editfield_t *ef = &cf->cf_editimpl;
Listbox_t *lb = &cf->cf_listimpl;
- const char *buffer = ef->ef_buffer;
+ const char *buffer = ef_get(ef);
char *outbuffer = cf->cf_buffer;
const ListboxItem_t *n;
if (! iscomplete) {
if (! cf->cf_open) { /* current value */
- strxcpy(outbuffer, (const char *)ef->ef_buffer, sizeof(ef->ef_buffer));
+ strxcpy(outbuffer, buffer, sizeof(cf->cf_buffer));
return outbuffer;
}
}
@@ -4578,7 +4713,11 @@ combofield_value_get(WCombofield_t *cf, int iscomplete)
/*FALLTHRU*/
default:
+#if defined(EWIDECHAR)
+ Wcstoutf8(ef->ef_restore, outbuffer, sizeof(cf->cf_buffer));
+#else
strxcpy(outbuffer, ef->ef_restore, sizeof(cf->cf_buffer));
+#endif
if (iscomplete) {
ef_restore(ef);
iscomplete = FALSE;
@@ -4590,7 +4729,7 @@ combofield_value_get(WCombofield_t *cf, int iscomplete)
}
if (iscomplete) {
- strxcpy(ef->ef_buffer, outbuffer, sizeof(ef->ef_buffer));
+ ef_set(ef, outbuffer);
}
return outbuffer;
}
@@ -4894,4 +5033,6 @@ combofield_callback(WCombofield_t *cf, WIDGETMSG_t msg, WIDGETARG_t p1, WIDGETAR
}
return FALSE;
}
+
/*end*/
+
diff --git a/gr/window.c b/gr/window.c
index 5a100e03..6da5261d 100644
--- a/gr/window.c
+++ b/gr/window.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_window_c,"$Id: window.c,v 1.41 2020/04/21 00:01:57 cvsuser Exp $")
+__CIDENT_RCSID(gr_window_c,"$Id: window.c,v 1.45 2021/10/17 03:54:22 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: window.c,v 1.41 2020/04/21 00:01:57 cvsuser Exp $
+/* $Id: window.c,v 1.45 2021/10/17 03:54:22 cvsuser Exp $
* Window basics.
*
*
@@ -23,6 +23,8 @@ __CIDENT_RCSID(gr_window_c,"$Id: window.c,v 1.41 2020/04/21 00:01:57 cvsuser Exp
#endif
#include
+#include "../libchartable/libchartable.h"
+#include "../libwidechar/widechar.h"
#include /* str_...()/sxprintf() */
#include "accum.h" /* acc_...() */
@@ -195,13 +197,13 @@ window_create(int type, const char *title, int x, int y, int w, int h)
acc_assign_int((accint_t) wp->w_num);
if (W_MENU == type) {
- wp->w_x = 0;
+ wp->w_x = 0;
wp->w_y = 0;
- wp->w_h = 1;
+ wp->w_h = 1;
wp->w_w = (uint16_t)(ttcols() - 1);
} else {
- const int titlelen = (title ? (int)strlen(title) : 0);
+ const int titlelen = (title ? (int)utf8_swidth(title) : 0); /*MCHAR*/
if (x < 0) { /* x within view */
x = 0;
@@ -273,8 +275,7 @@ window_create(int type, const char *title, int x, int y, int w, int h)
window_title(wp, "", (title ? title : ""));
window_append(wp);
- curwp = wp; /* current window */
- set_hooked();
+ set_curwp(wp); /* current window */
}
return (NULL == wp ? -1 : wp->w_num);
}
@@ -371,8 +372,7 @@ attach_buffer(WINDOW_t *wp, BUFFER_t *bp)
wp->w_status |= WFHARD;
window_title(wp, bp->b_title ? bp->b_title : sys_basename(bp->b_fname), NULL);
- curbp = bp;
- set_hooked();
+ set_curbp(bp);
}
}
diff --git a/grcpp/.cvsignore b/grcpp/.cvsignore
new file mode 100644
index 00000000..8c40b219
--- /dev/null
+++ b/grcpp/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.err
diff --git a/grmandoc/.cvsignore b/grmandoc/.cvsignore
index 865fe283..dc0bfd7d 100644
--- a/grmandoc/.cvsignore
+++ b/grmandoc/.cvsignore
@@ -1,4 +1,8 @@
-mdocml-1.12.*/
-mdocml-1.13.*/
-mandoc-1.14.*/
+mdocml-1.12.*
+mdocml-1.13.*
+mandoc-1.14.*
mdocversion.h
+Makefile
+.unpacked*
+*.err
+
diff --git a/grmandoc/.gitignore b/grmandoc/.gitignore
index 865fe283..3ec04542 100644
--- a/grmandoc/.gitignore
+++ b/grmandoc/.gitignore
@@ -2,3 +2,6 @@ mdocml-1.12.*/
mdocml-1.13.*/
mandoc-1.14.*/
mdocversion.h
+Makefile
+.unpacked*
+
diff --git a/grmandoc/Makefile.in b/grmandoc/Makefile.in
index b57d2760..162d8e9a 100644
--- a/grmandoc/Makefile.in
+++ b/grmandoc/Makefile.in
@@ -1,9 +1,9 @@
# -*- mode: mak; indent-tabs-mode: t; tab-width: 8 -*-
-# $Id: Makefile.in,v 1.26 2021/04/05 15:22:36 cvsuser Exp $
+# $Id: Makefile.in,v 1.27 2022/03/22 11:00:41 cvsuser Exp $
# libbsdmdoc and grmanddoc
#
#
-# Copyright (c) 2014 - 2021, Adam Young.
+# Copyright (c) 2014 - 2022, Adam Young.
# All rights reserved.
#
# This file is part of the GRIEF Editor.
diff --git a/grunch/.cvsignore b/grunch/.cvsignore
new file mode 100644
index 00000000..6a9be135
--- /dev/null
+++ b/grunch/.cvsignore
@@ -0,0 +1,5 @@
+yygen.h
+y.tab.c
+crntypes.h
+Makefile
+*.err
diff --git a/grunch/crlex.c b/grunch/crlex.c
index 61ab1748..5531e117 100644
--- a/grunch/crlex.c
+++ b/grunch/crlex.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_crlex_c,"$Id: crlex.c,v 1.36 2020/04/23 12:35:50 cvsuser Exp $")
+__CIDENT_RCSID(gr_crlex_c,"$Id: crlex.c,v 1.37 2021/06/07 16:04:23 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: crlex.c,v 1.36 2020/04/23 12:35:50 cvsuser Exp $
+/* $Id: crlex.c,v 1.37 2021/06/07 16:04:23 cvsuser Exp $
* Lexical analyser for the GRUNCH language.
*
*
@@ -236,6 +236,7 @@ static int get_line(lexer_t *lexer);
static void get_while(lexer_t *lexer, int chclass);
static void get_string(lexer_t *lexer, int wchar);
static void get_unquoted(lexer_t *lexer, const int end);
+static const char * utf8_decode(const void *src, const void *cpend, int *result);
static int utf8_encode(int ch, void *buffer);
static int get_character(lexer_t *lexer, int wchar);
static int get_escape(lexer_t *lexer, unsigned wchar, unsigned limit, int *value);
@@ -966,6 +967,88 @@ get_unquoted(lexer_t *lexer, const int end)
}
}
+/*
+ * 00000000-01111111 00-7F 0-127 Single-byte encoding (compatible with US-ASCII).
+ * 10000000-10111111 80-BF 128-191 Second, third, or fourth byte of a multi-byte sequence.
+ * 11000000-11000001 C0-C1 192-193 Overlong encoding: start of 2-byte sequence, but would encode a code point 127.
+ * 11000010-11011111 C2-DF 194-223 Start of 2-byte sequence.
+ * 11100000-11101111 E0-EF 224-239 Start of 3-byte sequence.
+ * 11110000-11110100 F0-F4 240-244 Start of 4-byte sequence.
+ * 11110101-11110111 F5-F7 245-247 Restricted by RFC 3629: start of 4-byte sequence for codepoint above 10FFFF.
+ * 11111000-11111011 F8-FB 248-251 Restricted by RFC 3629: start of 5-byte sequence.
+ * 11111100-11111101 FC-FD 252-253 Restricted by RFC 3629: start of 6-byte sequence.
+ * 11111110-11111111 FE-FF 254-255 Invalid: not defined by original UTF-8 specification.
+ */
+static const char *
+utf8_decode(const void *src, const void *cpend, int *result)
+{
+ register const unsigned char *t_src = (const unsigned char *)src;
+ unsigned char ch;
+ int32_t ret = 0;
+ int remain;
+
+ /*
+ // Bits Last code point Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
+ // 7 U+007F 0xxxxxxx
+ // 11 U+07FF 110xxxxx 10xxxxxx
+ // 16 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
+ // 21 U+1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ // 26 U+3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ // 31 U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ */
+ assert(src < cpend);
+ ch = *t_src++;
+
+ if (ch & 0x80) {
+ /* C0-C1 192-193 Overlong encoding: start of 2-byte sequence. */
+ if ((ch & 0xE0) == 0xC0) { /* C2-DF 194-223 Start of 2-byte sequence. */
+ remain = 1;
+ ret = ch & 0x1F;
+
+ } else if ((ch & 0xF0) == 0xE0) { /* E0-EF 224-239 Start of 3-byte sequence. */
+ remain = 2;
+ ret = ch & 0x0F;
+
+ } else if ((ch & 0xF8) == 0xF0) { /* F0-F4 240-244 Start of 4-byte sequence. */
+ remain = 3;
+ ret = ch & 0x07;
+
+ } else if ((ch & 0xFC) == 0xF8) { /* F8-FB 248-251 Start of 5-byte sequence. */
+ remain = 4;
+ ret = ch & 0x03;
+
+ } else if ((ch & 0xFE) == 0xFC) { /* FC-FD 252-253 Start of 6-byte sequence. */
+ remain = 5;
+ ret = ch & 0x01;
+
+ } else { /* invalid continuation (0x80 - 0xbf). */
+ ret = -ch;
+ goto done;
+ }
+
+ while (remain--) {
+ if (t_src >= (const unsigned char *)cpend) {
+ ret = -ret;
+ goto done;
+ }
+ ch = *t_src++;
+ if (0x80 != (0xc0 & ch)) { /* invalid secondary byte (0x80 - 0xbf). */
+ --t_src;
+ ret = -ret;
+ goto done;
+ }
+ ret <<= 6;
+ ret |= (ch & 0x3f);
+ }
+ } else {
+ ret = ch;
+ }
+
+done:;
+ *result = ret;
+ return (const void *)t_src;
+}
+
static int
utf8_encode(int ch, void *buffer)
@@ -1033,6 +1116,7 @@ utf8_encode(int ch, void *buffer)
static int
get_character(lexer_t *lexer, int wchar)
{
+ char buffer[6 + 1] = {0}; /* UTF8 working buffer */
int ch, error = 0;
int value = 0;
@@ -1059,14 +1143,11 @@ bad:; if (0 == ch) {
if (get_escape(lexer, wchar, FALSE, &ch) < 0) {
goto bad;
}
-
- if (wchar) { /* upper bytes */
- value = (value << 8) + ((ch & 0xFFFFFF00) >> 8);
- ch &= 0x00FF;
- }
}
- value = (value << 8) + ch;
+ value = ch;
+ if (nchars < (sizeof(buffer) - 1))
+ buffer[nchars] = ch;
++nchars;
if ('\'' == (ch = lexget(lexer))) {
@@ -1074,11 +1155,16 @@ bad:; if (0 == ch) {
}
}
- if (nchars > 1) {
- if (!error) {
+ if (nchars > 1 && !error) {
+ if (!wchar) {
crerrorx(RC_CHARACTER_WIDE, "character constant too large");
+ ++error;
+
+ } else if (nchars > 6 ||
+ utf8_decode(buffer, buffer + nchars, &value) != (buffer + nchars)) {
+ crerrorx(RC_CHARACTER_WIDE, "invalid multi-character character constant");
+ ++error;
}
- ++error;
}
}
diff --git a/grunch/crsubs.c b/grunch/crsubs.c
index 394d22c0..85ba1623 100644
--- a/grunch/crsubs.c
+++ b/grunch/crsubs.c
@@ -1,8 +1,8 @@
#include
-__CIDENT_RCSID(gr_crsubs_c,"$Id: crsubs.c,v 1.28 2020/04/23 12:35:50 cvsuser Exp $")
+__CIDENT_RCSID(gr_crsubs_c,"$Id: crsubs.c,v 1.29 2021/08/14 17:09:30 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: crsubs.c,v 1.28 2020/04/23 12:35:50 cvsuser Exp $
+/* $Id: crsubs.c,v 1.29 2021/08/14 17:09:30 cvsuser Exp $
* Parser ultities.
*
*
@@ -393,7 +393,7 @@ node_opt(int op, node_t *b, node_t *c)
return b;
case O_MOD:
if (0 == c->atom.ival) {
- crwarn(RC_ERROR, "constant expression modulo zero");
+ crwarn(RC_ERROR, "constant expression modulo by zero");
b->atom.ival = 0;
} else {
b->atom.ival %= c->atom.ival;
@@ -408,6 +408,22 @@ node_opt(int op, node_t *b, node_t *c)
case O_AND:
b->atom.ival &= c->atom.ival;
return b;
+ case O_LSHIFT:
+ if (0 == c->atom.ival) {
+ crwarn(RC_ERROR, "constant expression shift by zero");
+ } else if (c->atom.ival < 0 || c->atom.ival >= (sizeof(accint_t) * 8)) {
+ crwarn(RC_ERROR, "constant expression shift overflow");
+ }
+ b->atom.ival <<= c->atom.ival;
+ return b;
+ case O_RSHIFT:
+ if (0 == c->atom.ival) {
+ crwarn(RC_ERROR, "constant expression shift by zero");
+ } else if (c->atom.ival < 0 || c->atom.ival >= (sizeof(accint_t) * 8)) {
+ crwarn(RC_ERROR, "constant expression shift overflow");
+ }
+ b->atom.ival >>= c->atom.ival;
+ return b;
default:
break;
}
diff --git a/grunch/cry.y b/grunch/cry.y
index e1b9bdb1..43d8f0d1 100644
--- a/grunch/cry.y
+++ b/grunch/cry.y
@@ -1,5 +1,5 @@
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: cry.y,v 1.35 2021/04/05 09:18:23 cvsuser Exp $
+/* $Id: cry.y,v 1.36 2021/08/14 17:09:30 cvsuser Exp $
* grunch/crunch grammer, extended c99
*
*
@@ -525,9 +525,9 @@ additive_expression:
shift_expression:
additive_expression
| shift_expression O_LSHIFT additive_expression
- { $$ = node(O_LSHIFT, $1, $3); }
+ { $$ = node_opt(O_LSHIFT, $1, $3); }
| shift_expression O_RSHIFT additive_expression
- { $$ = node(O_RSHIFT, $1, $3); }
+ { $$ = node_opt(O_RSHIFT, $1, $3); }
;
relational_expression:
diff --git a/hlpdoc/.cvsignore b/hlpdoc/.cvsignore
index 48f2c2c9..a361cc61 100644
--- a/hlpdoc/.cvsignore
+++ b/hlpdoc/.cvsignore
@@ -3,5 +3,7 @@ doc/html/
doc/mandoc/
ndplus
Makefile
+*.err
+*.pdf
ref
diff --git a/include/asciidefs.h b/include/asciidefs.h
index 041a6fd7..461c59b7 100644
--- a/include/asciidefs.h
+++ b/include/asciidefs.h
@@ -1,17 +1,17 @@
#ifndef GR_ASCIIDEFS_H_INCLUDED
#define GR_ASCIIDEFS_H_INCLUDED
#include
-__CIDENT_RCSID(gr_asciidefs_h,"$Id: asciidefs.h,v 1.10 2019/03/15 23:03:05 cvsuser Exp $")
+__CIDENT_RCSID(gr_asciidefs_h,"$Id: asciidefs.h,v 1.11 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: asciidefs.h,v 1.10 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: asciidefs.h,v 1.11 2022/03/21 14:55:27 cvsuser Exp $
* ASCII character value definitions
* For portibality avoid where possible use of c/+cc escapes (ie. '\n').
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/chkalloc.h b/include/chkalloc.h
index f6ae7733..09f8ba44 100644
--- a/include/chkalloc.h
+++ b/include/chkalloc.h
@@ -1,11 +1,11 @@
#ifndef GR_CHKALLOC_H_INCLUDED
#define GR_CHKALLOC_H_INCLUDED
#include
-__CIDENT_RCSID(gr_chkalloc_h,"$Id: chkalloc.h,v 1.23 2020/06/03 14:17:01 cvsuser Exp $")
+__CIDENT_RCSID(gr_chkalloc_h,"$Id: chkalloc.h,v 1.24 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: chkalloc.h,v 1.23 2020/06/03 14:17:01 cvsuser Exp $
+/* $Id: chkalloc.h,v 1.24 2022/03/21 14:55:27 cvsuser Exp $
* Memory management interface.
*
* #define CHKALLOC_DEBUG 1
@@ -33,7 +33,7 @@ __CPRAGMA_ONCE
* CHKALLOC_WHERE
* Extended trace information.
*
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/config.hin b/include/config.hin
index 734115c8..5d972ca7 100644
--- a/include/config.hin
+++ b/include/config.hin
@@ -1,11 +1,11 @@
#ifndef CR_CONFIG_H_INCLUDED
#define CR_CONFIG_H_INCLUDED
#include
-__CIDENT_RCSID(config_h, "$Id: config.hin,v 1.54 2021/04/19 14:57:19 cvsuser Exp $")
+__CIDENT_RCSID(config_h, "$Id: config.hin,v 1.57 2021/08/02 16:10:31 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; set-indent: 4; -*- */
-/* $Id: config.hin,v 1.54 2021/04/19 14:57:19 cvsuser Exp $
+/* $Id: config.hin,v 1.57 2021/08/02 16:10:31 cvsuser Exp $
* Machine configuration.
*
*
@@ -79,6 +79,7 @@ __CPRAGMA_ONCE
#undef HAVE_STDARG_H
#undef HAVE_STDLIB_H
#undef HAVE_STDIO_H
+#undef HAVE_STDDEF_H
#undef HAVE_LIMITS_H
/* AC_HEADER_DIRENT */
@@ -115,6 +116,7 @@ __CPRAGMA_ONCE
#undef HAVE_SYS_UTSNAME_H
#undef HAVE_SYS_SELECT_H
#undef HAVE_SYS_SOCKET_H
+#undef HAVE_SYS_SENDFILE_H
#undef HAVE_SYS_WAIT_H
#undef HAVE_SYS_STAT_H
#undef HAVE_SYS_STATFS_H
@@ -138,6 +140,7 @@ __CPRAGMA_ONCE
#undef HAVE_THREAD_H
#undef HAVE_PTHREAD_H
+#undef HAVE_PTHREAD_PRIO_INHERIT
#undef HAVE_FCNTL_H
#undef HAVE_SHARE_H
@@ -170,6 +173,7 @@ __CPRAGMA_ONCE
#undef HAVE_ERR_H
#undef HAVE_FTS_H
+
/*
* Available allocator functionality
*/
@@ -223,6 +227,8 @@ __CPRAGMA_ONCE
#undef HAVE_NCURSESW_NCURSESW_H
#undef HAVE_NCURSESW_CURSES_H
+#undef HAVE_NCURSESW_TERMCAP_H
+#undef HAVE_NCURSESW_TERM_H
#undef HAVE_NCURSESW_H
#undef HAVE_CURSES_H
@@ -345,7 +351,7 @@ __CPRAGMA_ONCE
*/
/* environ support */
-
+
#undef HAVE_ENVIRON
#undef HAVE__ENVIRON
#undef HAVE___ENVIRON
@@ -379,9 +385,11 @@ __CPRAGMA_ONCE
#undef HAVE_SELECT
#undef HAVE_POLL
#undef HAVE_LINK
+#undef HAVE_STAT
#undef HAVE_LSTAT
#undef HAVE_SYMLINK
#undef HAVE_RENAME
+#undef HAVE_FSEEKO
#undef HAVE_FGETPOS
#undef HAVE_FSETPOS
@@ -458,6 +466,7 @@ __CPRAGMA_ONCE
#undef HAVE_PREAD
#undef HAVE_PWRITE
+#undef HAVE_SENDFILE
#undef HAVE_GETW
#undef HAVE_PUTW
@@ -486,6 +495,8 @@ __CPRAGMA_ONCE
#undef HAVE_STRINGLIST
#undef HAVE_REALLOCARRAY
+#undef HAVE_LIBNSL
+
#undef HAVE_SIGSETMASK
#undef HAVE_SIGACTION
#undef HAVE_SIGINTERRUPT
@@ -502,6 +513,7 @@ __CPRAGMA_ONCE
#undef HAVE_WMEMCMP
#undef HAVE_WMEMMOVE
#undef HAVE_WMEMCPY
+#undef HAVE_WCWIDTH
#undef HAVE_MMAP
#undef HAVE_MPROTECT
@@ -577,6 +589,7 @@ __CPRAGMA_ONCE
#undef HAVE_X11_XFT_XFT_H
#undef HAVE_X11_XKBLIB_H
#undef HAVE_X11_XLIB_H
+#undef HAVE_XFT_XLBLIB_H
#undef HAVE_XFT_XFT_H
#undef HAVE_XKBBELL
#undef HAVE_LIBX11
@@ -668,6 +681,7 @@ __CPRAGMA_ONCE
#undef HAVE_LIBGUESS
#undef HAVE_LIBGUESS_EXTENSIONS
#undef HAVE_LIBGUESS_H
+#undef HAVE_LIBGUESS_LIBGUESS_H
/* libmagic and magic.h */
#undef HAVE_LIBMAGIC
@@ -743,4 +757,3 @@ __CPRAGMA_ONCE
#define GRIEF_DATADIR "/usr/local/lib/grief/"
#endif /*CR_CONFIG_H_INCLUDED*/
-
diff --git a/include/edalt.h b/include/edalt.h
index 3c191462..e8009e41 100644
--- a/include/edalt.h
+++ b/include/edalt.h
@@ -1,15 +1,15 @@
#ifndef GR_EDALT_H_INCLUDED
#define GR_EDALT_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edalt_h,"$Id: edalt.h,v 1.27 2020/06/18 12:53:03 cvsuser Exp $")
+__CIDENT_RCSID(gr_edalt_h,"$Id: edalt.h,v 1.32 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edalt.h,v 1.27 2020/06/18 12:53:03 cvsuser Exp $
+/* $Id: edalt.h,v 1.32 2022/03/21 14:55:27 cvsuser Exp $
* Key definitions.
* ==noguard==
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
@@ -36,41 +36,13 @@ __CPRAGMA_ONCE
/*
* The following scheme is used for encoding function keys.
*
- * This scheme is used because it simplifies converting ASCII key names to the
- * internal codes and vice-versa. Also we keep the internal keycodes out of the
- * ASCII range so users are free to use those for input if necessary, e.g. on
- * foreign language keyboards.
+ * Unicode defines a codespace for 1,114,112 code points in range
+ * 0 to 10FFFF leaving the top bits.
*
+ * These are utilised for attributes are used to create seperate
+ * namespaces for UNICODE, FUNCTION and others.
*
- * 0x000..0x0ff ASCII ASCII range.
- * 0x100..0x1ff Fn keys Support for upto 255 unshifted function keys
- * 0x200..0x2ff Keypad Upto 256 keypad keys.
- * 0x300..0x3ff Misc Miscellaneous
- * 0x400..0x7ff Multikey Used when user does something like:
- * assign_to_key("xyz", .. ie. multi-key stroke.
- * 0x800..0x8ff Private Private key definitions for users.
- * 0x900..0x91f Button down Mouse buttons
- * 0x920..0x93f Button up Mouse buttons
- * 0x940..0x95f Pointer motion Mouse buttons
- *
- * These ranges can be OR'ed with the following bits to indicate
- * a modifier key is in operation.
- *
- * 0x1000 SHIFT
- * 0x2000 CTRL Not used for ASCII range.
- * 0x4000 META
- *
- */
-
-/*
- * New Key encoding:
- *
- * Unicode defines a codespace for 1,114,112 code points in range
- * 0 to 10FFFF leaving the top bits.
- *
- * These are utilised for attributes are used to create seperate
- * namespaces for ASCII, UNICODE, FUNCTION and others, plus
- * Shift, Ctrl and Meta modifiers.
+ * Within these ranges can be OR'ed with the modifiers SHIFT, CTRL and META.
*
* -----------------------------------------------------------------
* | attributes | character |
@@ -78,34 +50,21 @@ __CPRAGMA_ONCE
* 4 3 2 1 4 3 2 1 4 3 2 1 4 2 3 1 4 3 2 1 4 2 3 1 4 3 2 1 4 2 3 1
* 1 f . . . f . . . f . . . f . . . f . . .
*
- * x Shift
- * x Ctrl/control
- * x Meta
- * s . . . r r r r Character ranges/namespaces
+ * x Shift - MOD_SHIFT
+ * x Ctrl/control - MOD_CTRL
+ * x Meta - MOD_META
+ * x App - MOD_APP
+ * s . r r r r . Character ranges/namespaces - RANGE_MASK
*
-
+ * RANGE_CHARACTER, RANGE_FUNCTION, RANGE_KEYPAD,
+ * RANGE_MISC, RANGE_MULTIKEY, RANGE_PRIVATE, RANGE_BUTTON
+ *
+ * s = sign/reserved.
+ * . = reserved/unused.
+ *
+
typedef int32_t KEY;
-#define KEY_MASK 0x001fffff // 0..10ffff
-#define KEY_ATTRMASK 0x8fe00000
-
-#define RANGE_ASCII 0x00000000 // namespaces
-#define RANGE_UNICODE 0x01000000
-#define RANGE_FN 0x02000000
-#define RANGE_KEYPAD 0x03000000
-#define RANGE_MISC 0x04000000
-#define RANGE_MULTIKEY 0x05000000
-#define RANGE_PRIVATE 0x0a000000
-#define RANGE_BUTTON 0x0b000000
-#define RANGE_MASK 0x0f000000
-
-#define MOD_SHIFT 0x00200000 // modifiers
-#define MOD_CTRL 0x00400000
-#define MOD_META 0x00800000
-
-#define KEY_VOID 0x001fffff
-
- *
*/
#if defined(_WIN32) || defined(WIN32)
@@ -138,6 +97,7 @@ typedef int32_t KEY;
#undef KEY_REPLACE
#undef KEY_ENTER
#undef KEY_BACKSPACE
+#undef KEY_BREAK
#endif
/*
@@ -153,36 +113,40 @@ typedef int32_t KEY;
#define KEY_TAB __TAB
#define KEY_ENTER __ENTER
#define KEY_NEWLINE '\n'
-#define KEY_WINCH 0x7ffe
-#define KEY_VOID 0x7fff
+#define KEY_DELETE 0x7f
-/*
- * Macro to check whether key is a normal ASCII key.
+/*
+ * Namespaces and modifiers.
*/
-#define IS_ASCII(x) ((x & ~KEY_MASK) == 0)
-#define IS_MULTIKEY(x) ((x) >= RANGE_MULTIKEY && (x) <= RANGE_MULTIKEY + MULTIKEY_SIZE)
-#define KEY_MASK 0x00ff
+#define KEY_MASK 0x001fffff // 0..10ffff
+#define RANGE_CHARACTER 0x00000000 // namespaces
+#define RANGE_FUNCTION (1 << 26)
+#define RANGE_KEYPAD (2 << 26)
+#define RANGE_MISC (3 << 26)
+#define RANGE_MULTIKEY (4 << 26)
+#define RANGE_PRIVATE (5 << 26)
+#define RANGE_BUTTON (6 << 26)
+#define RANGE_MAX (15 << 26)
+#define RANGE_MASK 0x3c000000
-/*
- * Modifier bits.
- */
-#define MOD_SHIFT 0x1000
-#define MOD_CTRL 0x2000
-#define MOD_META 0x4000
+#define MULTIKEY_SIZE 0x0400
+#define IS_CHARACTER(x) (((x) & ~KEY_MASK) == 0) // unmodified character.
+#define IS_FUNCTION(x) (((x) & RANGE_MASK) == RANGE_FUNCTION) // function key.
+#define IS_MULTIKEY(x) ((x) >= RANGE_MULTIKEY && (x) <= (RANGE_MULTIKEY + MULTIKEY_SIZE))
+#define IS_BUTTON(x) (((x) & RANGE_MASK) == RANGE_BUTTON) // mouse button.
+
+#define MOD_SHIFT 0x00200000 // modifiers
+#define MOD_CTRL 0x00400000
+#define MOD_META 0x00800000
+#define MOD_APP 0x01000000 // reserved
+#define MOD_MASK 0x01e00000
/*
- * Key ranges.
+ * Specials
*/
-#define RANGE_ASCII 0x0000
-#define RANGE_FN 0x0100
-#define RANGE_KEYPAD 0x0200
-#define RANGE_MISC 0x0300
-#define RANGE_MULTIKEY 0x0400 /* 0x400 .. 0x7ff */
-#define RANGE_PRIVATE 0x0800 /* 0x800 .. 0x8ff */
-#define RANGE_BUTTON 0x0900
-#define RANGE_MASK 0x0f00
-
-#define MULTIKEY_SIZE 0x0400
+#define KEY_VOID 0x001fffff // null
+#define KEY_WINCH 0x001ffffe // winch/resize event
+#define KEY_UNICODE 0x001ffff0 // keyboard special
/*
* Control characters
@@ -231,11 +195,11 @@ typedef int32_t KEY;
/*
* Function key definitions.
*/
-#define F(__x) (RANGE_FN + (__x) - 1)
-#define SF(__x) (MOD_SHIFT | (RANGE_FN + (__x) - 1))
-#define CF(__x) (MOD_CTRL | (RANGE_FN + (__x) - 1))
-#define CSF(__x) (MOD_CTRL | MOD_SHIFT | (RANGE_FN + (__x) - 1))
-#define AF(__x) (MOD_META | (RANGE_FN + (__x) - 1))
+#define F(__x) (RANGE_FUNCTION + (__x) - 1)
+#define SF(__x) (MOD_SHIFT | (RANGE_FUNCTION + (__x) - 1))
+#define CF(__x) (MOD_CTRL | (RANGE_FUNCTION + (__x) - 1))
+#define CSF(__x) (MOD_CTRL | MOD_SHIFT | (RANGE_FUNCTION + (__x) - 1))
+#define AF(__x) (MOD_META | (RANGE_FUNCTION + (__x) - 1))
/*
* Alt-letter definitions.
@@ -336,7 +300,7 @@ typedef int32_t KEY;
/*
* Control keypad keys.
*/
-#define __CTRL_KEYPAD(__x) (MOD_CTRL | RANGE_KEYPAD | (__x))
+#define __CTRL_KEYPAD(__x) (MOD_CTRL | RANGE_KEYPAD | (__x))
#define CTRL_KEYPAD_0 __CTRL_KEYPAD(0)
#define CTRL_KEYPAD_1 __CTRL_KEYPAD(1)
#define CTRL_KEYPAD_2 __CTRL_KEYPAD(2)
@@ -453,6 +417,7 @@ typedef int32_t KEY;
#define KEY_OPEN (RANGE_MISC | 20)
#define KEY_SAVE (RANGE_MISC | 21)
#define KEY_MENU (RANGE_MISC | 22)
+#define KEY_BREAK (RANGE_MISC | 23)
#define WHEEL_UP (RANGE_MISC | 31) /* Mouse scroll wheel */
#define WHEEL_DOWN (RANGE_MISC | 32)
diff --git a/include/edassert.h b/include/edassert.h
index ab183a2b..2c8b6f9d 100644
--- a/include/edassert.h
+++ b/include/edassert.h
@@ -1,15 +1,15 @@
#ifndef GR_EDASSERT_H_INCLUDED
#define GR_EDASSERT_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edassert_h,"$Id: edassert.h,v 1.14 2019/03/15 23:03:05 cvsuser Exp $")
+__CIDENT_RCSID(gr_edassert_h,"$Id: edassert.h,v 1.15 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edassert.h,v 1.14 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: edassert.h,v 1.15 2022/03/21 14:55:27 cvsuser Exp $
* Custom assert interface
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edcm.h b/include/edcm.h
index 8b07abcb..3f3de694 100644
--- a/include/edcm.h
+++ b/include/edcm.h
@@ -1,16 +1,16 @@
#ifndef GR_EDCM_H_INCLUDED
#define GR_EDCM_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edcm_h,"$Id: edcm.h,v 1.21 2020/04/20 23:21:26 cvsuser Exp $")
+__CIDENT_RCSID(gr_edcm_h,"$Id: edcm.h,v 1.22 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edcm.h,v 1.21 2020/04/20 23:21:26 cvsuser Exp $
+/* $Id: edcm.h,v 1.22 2022/03/21 14:55:27 cvsuser Exp $
* clisp macro constructs.
*
*
*
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edconfig.h b/include/edconfig.h
index 0af0adba..dee213d0 100644
--- a/include/edconfig.h
+++ b/include/edconfig.h
@@ -1,11 +1,11 @@
#ifndef GR_EDCONFIG_H_INCLUDED
#define GR_EDCONFIG_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edconfig_h,"$Id: edconfig.h,v 1.12 2019/03/15 23:03:05 cvsuser Exp $")
+__CIDENT_RCSID(gr_edconfig_h,"$Id: edconfig.h,v 1.13 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edconfig.h,v 1.12 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: edconfig.h,v 1.13 2022/03/21 14:55:27 cvsuser Exp $
* Configuration.
*
* GRINIT_FILE
@@ -29,7 +29,7 @@ __CPRAGMA_ONCE
* GRINIT_OBJECT
* Initialisation macro object, containing GRINIT_MACRO.
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/eddebug.h b/include/eddebug.h
index caa525ef..aeea538a 100644
--- a/include/eddebug.h
+++ b/include/eddebug.h
@@ -1,16 +1,16 @@
#ifndef GR_EDDEBUG_H_INCLUDED
#define GR_EDDEBUG_H_INCLUDED
#include
-__CIDENT_RCSID(gr_eddebug_h,"$Id: eddebug.h,v 1.27 2019/03/15 23:03:05 cvsuser Exp $")
+__CIDENT_RCSID(gr_eddebug_h,"$Id: eddebug.h,v 1.28 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: eddebug.h,v 1.27 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: eddebug.h,v 1.28 2022/03/21 14:55:27 cvsuser Exp $
* Debug functions.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/eddir.h b/include/eddir.h
index 163b46f6..304b9191 100644
--- a/include/eddir.h
+++ b/include/eddir.h
@@ -1,16 +1,16 @@
#ifndef GR_EDDIR_H_INCLUDED
#define GR_EDDIR_H_INCLUDED
#include
-__CIDENT_RCSID(gr_eddir_h,"$Id: eddir.h,v 1.13 2020/06/18 12:52:43 cvsuser Exp $")
+__CIDENT_RCSID(gr_eddir_h,"$Id: eddir.h,v 1.14 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: eddir.h,v 1.13 2020/06/18 12:52:43 cvsuser Exp $
+/* $Id: eddir.h,v 1.14 2022/03/21 14:55:27 cvsuser Exp $
* Directory management.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edendian.h b/include/edendian.h
index 82de5a28..61a27157 100644
--- a/include/edendian.h
+++ b/include/edendian.h
@@ -1,16 +1,16 @@
#ifndef GR_EDENDIAN_H_INCLUDED
#define GR_EDENDIAN_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edendian_h,"$Id: edendian.h,v 1.14 2019/03/15 23:03:05 cvsuser Exp $")
+__CIDENT_RCSID(gr_edendian_h,"$Id: edendian.h,v 1.15 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edendian.h,v 1.14 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: edendian.h,v 1.15 2022/03/21 14:55:27 cvsuser Exp $
* Endian interface.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edenv.h b/include/edenv.h
index 11ca1c76..d920fc3e 100644
--- a/include/edenv.h
+++ b/include/edenv.h
@@ -1,16 +1,16 @@
#ifndef GR_EDENV_H_INCLUDED
#define GR_EDENV_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edenv_h,"$Id: edenv.h,v 1.16 2019/03/15 23:03:05 cvsuser Exp $")
+__CIDENT_RCSID(gr_edenv_h,"$Id: edenv.h,v 1.17 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edenv.h,v 1.16 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: edenv.h,v 1.17 2022/03/21 14:55:27 cvsuser Exp $
* Environment interface.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edfeatures.h b/include/edfeatures.h
index 187b7d3b..0c19f37f 100644
--- a/include/edfeatures.h
+++ b/include/edfeatures.h
@@ -1,16 +1,16 @@
#ifndef GR_EDFEATURES_H_INCLUDED
#define GR_EDFEATURES_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edfeatures_h,"$Id: edfeatures.h,v 1.13 2019/03/15 23:03:05 cvsuser Exp $")
+__CIDENT_RCSID(gr_edfeatures_h,"$Id: edfeatures.h,v 1.15 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edfeatures.h,v 1.13 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: edfeatures.h,v 1.15 2022/03/21 14:55:27 cvsuser Exp $
* Editor features.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
@@ -101,8 +101,7 @@ __CBEGIN_DECLS
#define TF_ENCODING 100 /* terminal character encoding */
#define TF_ENCODING_GUESS 101 /* text encoding guess specification */
-#define TF_UNICODE_VERSION 102 /* UNICODE version, 300 = 3.00 */
-#define TF_UNICODE_WIDTH 103 /* width table version */
+#define TF_UNICODE_VERSION 102 /* UNICODE version; eg. "6.0.0" */
/*--end--*/
/*--export--defines--*/
@@ -234,8 +233,7 @@ struct _features {
int pt_screen_rows; /* INT, Screen rows. */
int pt_screen_cols; /* INT, Screen columns. */
- int pt_unicode_version; /* INT, UNICODE version. */
- int pt_unicode_width; /* INT, UNICODE width version. */
+ char pt_unicode_version[PT_NAME]; /* STRING, UNICODE version. */
char pt_encoding[PT_NAME]; /* STRING, Encoding. */
char pt_colormap[512]; /* STRING, XTERM color map. */
diff --git a/include/edfileio.h b/include/edfileio.h
index bba966d0..af54344e 100644
--- a/include/edfileio.h
+++ b/include/edfileio.h
@@ -1,17 +1,15 @@
#ifndef GR_EDFILEIO_H_INCLUDED
#define GR_EDFILEIO_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edfileio_h,"$Id: edfileio.h,v 1.16 2020/06/18 12:53:31 cvsuser Exp $")
+__CIDENT_RCSID(gr_edfileio_h,"$Id: edfileio.h,v 1.18 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edfileio.h,v 1.16 2020/06/18 12:53:31 cvsuser Exp $
+/* $Id: edfileio.h,v 1.18 2022/03/21 14:55:27 cvsuser Exp $
* File input/output functionality system api names.
* Required by non-posix environments (ie. WIN32).
*
- *
- *
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
@@ -58,17 +56,11 @@ __CBEGIN_DECLS
/*
* MSVC and WATCOMC
*/
-#define fileio_open(_fn, _of, _om) _open(_fn, _of, _om)
+#define fileio_open(_fn, _of, _om) w32_open(_fn, _of, _om)
#define fileio_close(_fd) _close(_fd)
#define fileio_read(_fd, _ib, _is) _read(_fd, _ib, _is)
#define fileio_write(_fd, _ob, _is) _write(_fd, _ob, _is)
#define fileio_lseek(_fd, _o, _w) _lseek(_fd, _o, _w)
-
-#define fileio_access(_fn, _m) _access(_fn, _m)
-#define fileio_chmod(_fn, _m) _chmod(_fn, _m)
-#define fileio_unlink(_fn) _unlink(_fn)
-#define fileio_mkdir(_dn, _m) w32_mkdir(_dn, _m)
-
#define fileio_fdopen(_fd, _om) _fdopen(_fd, _om)
#define fileio_fileno(_fs) _fileno(_fs)
#define fileio_umask(_mk) _umask(_mk)
@@ -79,12 +71,6 @@ __CBEGIN_DECLS
#define fileio_read(_fd, _ib, _is) read(_fd, _ib, _is)
#define fileio_write(_fd, _ob, _is) write(_fd, _ob, _is)
#define fileio_lseek(_fd, _o, _w) lseek(_fd, _o, _w)
-
-#define fileio_access(_fn, _m) access(_fn, _m)
-#define fileio_chmod(_fn, _m) chmod(_fn, _m)
-#define fileio_unlink(_fn) unlink(_fn)
-#define fileio_mkdir(_dn, _m) mkdir(_dn, _m)
-
#define fileio_fdopen(_fd, _om) fdopen(_fd, _om)
#define fileio_fileno(_fs) fileno(_fs)
#define fileio_umask(_mk) umask(_mk)
@@ -93,4 +79,5 @@ __CBEGIN_DECLS
__CEND_DECLS
#endif /*GR_EDFILEIO_H_INCLUDED*/
+
/*end*/
diff --git a/include/edgetopt.h b/include/edgetopt.h
index 57fdbcd5..c91f557e 100644
--- a/include/edgetopt.h
+++ b/include/edgetopt.h
@@ -1,16 +1,16 @@
#ifndef GR_EDGETOPT_H_INCLUDED
#define GR_EDGETOPT_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edgetopt_h,"$Id: edgetopt.h,v 1.17 2020/06/18 12:53:56 cvsuser Exp $")
+__CIDENT_RCSID(gr_edgetopt_h,"$Id: edgetopt.h,v 1.18 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edgetopt.h,v 1.17 2020/06/18 12:53:56 cvsuser Exp $
+/* $Id: edgetopt.h,v 1.18 2022/03/21 14:55:27 cvsuser Exp $
* getopt() interface/implemenation.
*
*
*
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edhandles.h b/include/edhandles.h
index 632bdfe5..fd65b264 100644
--- a/include/edhandles.h
+++ b/include/edhandles.h
@@ -1,16 +1,16 @@
#ifndef GR_EDHANDLES_H_INCLUDED
#define GR_EDHANDLES_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edhandles_h,"$Id: edhandles.h,v 1.7 2019/03/15 23:03:05 cvsuser Exp $")
+__CIDENT_RCSID(gr_edhandles_h,"$Id: edhandles.h,v 1.8 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edhandles.h,v 1.7 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: edhandles.h,v 1.8 2022/03/21 14:55:27 cvsuser Exp $
* Internal handle base identifiers.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edheaders.h b/include/edheaders.h
index c81d646c..61d9d16a 100644
--- a/include/edheaders.h
+++ b/include/edheaders.h
@@ -1,16 +1,16 @@
#ifndef GR_EDHEADERS_H_INCLUDED
#define GR_EDHEADERS_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edheaders_h,"$Id: edheaders.h,v 1.16 2019/03/15 23:03:05 cvsuser Exp $")
+__CIDENT_RCSID(gr_edheaders_h,"$Id: edheaders.h,v 1.17 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edheaders.h,v 1.16 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: edheaders.h,v 1.17 2022/03/21 14:55:27 cvsuser Exp $
* System headers.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edidentifier.h b/include/edidentifier.h
index af9bc39c..7a6de5ad 100644
--- a/include/edidentifier.h
+++ b/include/edidentifier.h
@@ -2,7 +2,7 @@
#define GR_EDIDENTIFIER_H_INCLUDED
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edidentifier.h,v 1.17 2019/03/15 23:03:05 cvsuser Exp $
+/* $Id: edidentifier.h,v 1.18 2022/03/21 14:55:27 cvsuser Exp $
* Compiler specific object identify functionality.
*
* __CIDENT(description)
@@ -11,7 +11,7 @@
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/editor.h b/include/editor.h
index 6d55ed12..c6e41596 100644
--- a/include/editor.h
+++ b/include/editor.h
@@ -1,16 +1,16 @@
#ifndef GR_EDITOR_H_INCLUDED
#define GR_EDITOR_H_INCLUDED
#include
-__CIDENT_RCSID(gr_editor_h,"$Id: editor.h,v 1.35 2019/03/15 23:03:08 cvsuser Exp $")
+__CIDENT_RCSID(gr_editor_h,"$Id: editor.h,v 1.36 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: editor.h,v 1.35 2019/03/15 23:03:08 cvsuser Exp $
+/* $Id: editor.h,v 1.36 2022/03/21 14:55:27 cvsuser Exp $
* GRIEF Editor global definitions.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edlargefile.h b/include/edlargefile.h
index 0ec07d09..8d653147 100644
--- a/include/edlargefile.h
+++ b/include/edlargefile.h
@@ -1,16 +1,16 @@
#ifndef GR_EDLARGEFILE_H_INCLUDED
#define GR_EDLARGEFILE_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edlargefile_h,"$Id: edlargefile.h,v 1.10 2019/03/15 23:03:08 cvsuser Exp $")
+__CIDENT_RCSID(gr_edlargefile_h,"$Id: edlargefile.h,v 1.11 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edlargefile.h,v 1.10 2019/03/15 23:03:08 cvsuser Exp $
+/* $Id: edlargefile.h,v 1.11 2022/03/21 14:55:27 cvsuser Exp $
* Large file support interface.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edmacros.h b/include/edmacros.h
index 789ee381..d8cb4c2d 100644
--- a/include/edmacros.h
+++ b/include/edmacros.h
@@ -1,14 +1,14 @@
#ifndef GR_EDMACROS_H_INCLUDED
#define GR_EDMACROS_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edmacros_h,"$Id: edmacros.h,v 1.20 2020/04/21 21:21:14 cvsuser Exp $")
+__CIDENT_RCSID(gr_edmacros_h,"$Id: edmacros.h,v 1.21 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edmacros.h,v 1.20 2020/04/21 21:21:14 cvsuser Exp $
+/* $Id: edmacros.h,v 1.21 2022/03/21 14:55:27 cvsuser Exp $
* Macro and symbolic interpreter information.
*
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edopcode.h b/include/edopcode.h
index 6a25fcc6..14463e21 100644
--- a/include/edopcode.h
+++ b/include/edopcode.h
@@ -1,16 +1,16 @@
#ifndef GR_EDOPCODE_H_INCLUDED
#define GR_EDOPCODE_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edopcode_h,"$Id: edopcode.h,v 1.21 2020/04/21 21:21:14 cvsuser Exp $")
+__CIDENT_RCSID(gr_edopcode_h,"$Id: edopcode.h,v 1.22 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edopcode.h,v 1.21 2020/04/21 21:21:14 cvsuser Exp $
+/* $Id: edopcode.h,v 1.22 2022/03/21 14:55:27 cvsuser Exp $
* List types.
*
*
*
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edpack0.h b/include/edpack0.h
index 64e4a6d1..36c1ac6f 100644
--- a/include/edpack0.h
+++ b/include/edpack0.h
@@ -1,9 +1,9 @@
/* -*- mode: c; indent-width: 4; -*-
- * $Id: edpack0.h,v 1.5 2019/03/15 23:03:08 cvsuser Exp $
+ * $Id: edpack0.h,v 1.6 2022/03/21 14:55:27 cvsuser Exp $
* Structure packing.
* ==noguard==
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edpack1.h b/include/edpack1.h
index 4959b56a..0918564a 100644
--- a/include/edpack1.h
+++ b/include/edpack1.h
@@ -1,9 +1,9 @@
/* -*- mode: c; indent-width: 4; -*-
- * $Id: edpack1.h,v 1.5 2019/03/15 23:03:09 cvsuser Exp $
+ * $Id: edpack1.h,v 1.6 2022/03/21 14:55:27 cvsuser Exp $
* Structure packing.
* ==noguard==
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edpackage.h.in b/include/edpackage.h.in
index c778b99d..6ad7317d 100644
--- a/include/edpackage.h.in
+++ b/include/edpackage.h.in
@@ -1,15 +1,15 @@
#ifndef GR_EDPACKAGE_H_INCLUDED
#define GR_EDPACKAGE_H_INCLUDED
#include
-__CIDENT_RCSID(edpackage_h, "$Id: edpackage.h.in,v 1.7 2020/06/18 20:35:17 cvsuser Exp $")
+__CIDENT_RCSID(edpackage_h, "$Id: edpackage.h.in,v 1.8 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: h; set-indent: 4; -*- */
-/* $Id: edpackage.h.in,v 1.7 2020/06/18 20:35:17 cvsuser Exp $
+/* $Id: edpackage.h.in,v 1.8 2022/03/21 14:55:27 cvsuser Exp $
* Package configuration.
*
*
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edpaths.h b/include/edpaths.h
index 89278bac..094403e4 100644
--- a/include/edpaths.h
+++ b/include/edpaths.h
@@ -1,11 +1,11 @@
#ifndef GR_EDPATHS_H_INCLUDED
#define GR_EDPATHS_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edpaths_h,"$Id: edpaths.h,v 1.19 2020/06/18 12:52:11 cvsuser Exp $")
+__CIDENT_RCSID(gr_edpaths_h,"$Id: edpaths.h,v 1.20 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edpaths.h,v 1.19 2020/06/18 12:52:11 cvsuser Exp $
+/* $Id: edpaths.h,v 1.20 2022/03/21 14:55:27 cvsuser Exp $
* Default system paths ...
*
* Example:
@@ -14,7 +14,7 @@ __CPRAGMA_ONCE
*
* o Win32, ROOT=C:/Program Files/Grief
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edrefobj.h b/include/edrefobj.h
index ec244cd8..1578760a 100644
--- a/include/edrefobj.h
+++ b/include/edrefobj.h
@@ -1,16 +1,16 @@
#ifndef GR_EDREFOBJ_H_INCLUDED
#define GR_EDREFOBJ_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edrefobj_h,"$Id: edrefobj.h,v 1.21 2019/03/15 23:03:09 cvsuser Exp $")
+__CIDENT_RCSID(gr_edrefobj_h,"$Id: edrefobj.h,v 1.22 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edrefobj.h,v 1.21 2019/03/15 23:03:09 cvsuser Exp $
+/* $Id: edrefobj.h,v 1.22 2022/03/21 14:55:27 cvsuser Exp $
* Reference strings
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edringbuf.h b/include/edringbuf.h
index 7e571283..9b44d4b9 100644
--- a/include/edringbuf.h
+++ b/include/edringbuf.h
@@ -1,16 +1,16 @@
#ifndef GR_EDRINGBUF_H_INCLUDED
#define GR_EDRINGBUF_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edringbuf_h,"$Id: edringbuf.h,v 1.7 2019/03/15 23:03:09 cvsuser Exp $")
+__CIDENT_RCSID(gr_edringbuf_h,"$Id: edringbuf.h,v 1.8 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edringbuf.h,v 1.7 2019/03/15 23:03:09 cvsuser Exp $
+/* $Id: edringbuf.h,v 1.8 2022/03/21 14:55:27 cvsuser Exp $
* Basic binary ringbuffer ...
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edstacktrace.h b/include/edstacktrace.h
index a07a4a08..72b21e19 100644
--- a/include/edstacktrace.h
+++ b/include/edstacktrace.h
@@ -1,16 +1,16 @@
#ifndef GR_EDSTACKTRACE_H_INCLUDED
#define GR_EDSTACKTRACE_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edstacktrace_h,"$Id: edstacktrace.h,v 1.7 2019/03/15 23:03:09 cvsuser Exp $")
+__CIDENT_RCSID(gr_edstacktrace_h,"$Id: edstacktrace.h,v 1.8 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edstacktrace.h,v 1.7 2019/03/15 23:03:09 cvsuser Exp $
+/* $Id: edstacktrace.h,v 1.8 2022/03/21 14:55:27 cvsuser Exp $
* Diagnostics support.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edstdarg.h b/include/edstdarg.h
index bce44595..8682900b 100644
--- a/include/edstdarg.h
+++ b/include/edstdarg.h
@@ -1,17 +1,18 @@
#ifndef GR_EDSTDARG_H_INCLUDED
#define GR_EDSTDARG_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edstdarg_h,"$Id: edstdarg.h,v 1.1 2019/01/25 15:50:42 cvsuser Exp $")
+__CIDENT_RCSID(gr_edstdarg_h,"$Id: edstdarg.h,v 1.2 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edstdarg.h,v 1.1 2019/01/25 15:50:42 cvsuser Exp $
+/* $Id: edstdarg.h,v 1.2 2022/03/21 14:55:27 cvsuser Exp $
* stdarg() interface/implemenation.
*
*
* Copyright (c) Adam Young.
* All rights reserved.
*
+ * Copyright (c) 1998 - 2022, Adam Young.
* This file is part of the GRIEF Editor.
*
* The GRIEF Editor is free software: you can redistribute it
diff --git a/include/edstruct.h b/include/edstruct.h
index af62a374..6e113522 100644
--- a/include/edstruct.h
+++ b/include/edstruct.h
@@ -1,16 +1,16 @@
#ifndef GR_EDSTRUCT_H_INCLUDED
#define GR_EDSTRUCT_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edstruct_h,"$Id: edstruct.h,v 1.69 2020/06/18 12:51:55 cvsuser Exp $")
+__CIDENT_RCSID(gr_edstruct_h,"$Id: edstruct.h,v 1.71 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edstruct.h,v 1.69 2020/06/18 12:51:55 cvsuser Exp $
+/* $Id: edstruct.h,v 1.71 2022/03/21 14:55:27 cvsuser Exp $
* Window, buffer, line and character-map definitions.
*
*
*
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
@@ -75,7 +75,7 @@ enum _marks {
* Key table element
*/
struct k_tbl {
- uint16_t key;
+ KEY key;
const char * name;
};
diff --git a/include/edsym.h b/include/edsym.h
index e40b1b4b..d7890ca5 100644
--- a/include/edsym.h
+++ b/include/edsym.h
@@ -1,16 +1,16 @@
#ifndef GR_EDSYM_H_INCLUDED
#define GR_EDSYM_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edsym_h,"$Id: edsym.h,v 1.23 2020/04/21 21:21:14 cvsuser Exp $")
+__CIDENT_RCSID(gr_edsym_h,"$Id: edsym.h,v 1.24 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edsym.h,v 1.23 2020/04/21 21:21:14 cvsuser Exp $
+/* $Id: edsym.h,v 1.24 2022/03/21 14:55:27 cvsuser Exp $
* Symbol management.
*
*
*
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edtermcap.h b/include/edtermcap.h
index b47139b0..653d612f 100644
--- a/include/edtermcap.h
+++ b/include/edtermcap.h
@@ -1,16 +1,16 @@
#ifndef GR_EDTERMCAP_H_INCLUDED
#define GR_EDTERMCAP_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edtermcap_h,"$Id: edtermcap.h,v 1.13 2019/03/15 23:03:10 cvsuser Exp $")
+__CIDENT_RCSID(gr_edtermcap_h,"$Id: edtermcap.h,v 1.14 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edtermcap.h,v 1.13 2019/03/15 23:03:10 cvsuser Exp $
+/* $Id: edtermcap.h,v 1.14 2022/03/21 14:55:27 cvsuser Exp $
* Terminal interface.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edtermio.h b/include/edtermio.h
index 102c92b4..32333c56 100644
--- a/include/edtermio.h
+++ b/include/edtermio.h
@@ -1,16 +1,16 @@
#ifndef GR_EDTERMIO_H_INCLUDED
#define GR_EDTERMIO_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edtermio_h,"$Id: edtermio.h,v 1.13 2019/03/15 23:03:10 cvsuser Exp $")
+__CIDENT_RCSID(gr_edtermio_h,"$Id: edtermio.h,v 1.14 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edtermio.h,v 1.13 2019/03/15 23:03:10 cvsuser Exp $
+/* $Id: edtermio.h,v 1.14 2022/03/21 14:55:27 cvsuser Exp $
* Terminal i/o related definitions.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edthreads.h b/include/edthreads.h
index 54be4a14..ff1349ea 100644
--- a/include/edthreads.h
+++ b/include/edthreads.h
@@ -1,18 +1,18 @@
#ifndef GR_EDTHREADS_H_INCLUDED
#define GR_EDTHREADS_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edthreads_h,"$Id: edthreads.h,v 1.16 2021/04/03 03:42:53 cvsuser Exp $")
+__CIDENT_RCSID(gr_edthreads_h,"$Id: edthreads.h,v 1.17 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edthreads.h,v 1.16 2021/04/03 03:42:53 cvsuser Exp $
+/* $Id: edthreads.h,v 1.17 2022/03/21 14:55:27 cvsuser Exp $
* Threads interface
* ISO/IEC 9899:201x Committee Draft
* April 12, 2011 N1570
*
*
*
- * Copyright (c) 1998 - 2021, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edthreads_pthread.h b/include/edthreads_pthread.h
index f94ec236..970241b8 100644
--- a/include/edthreads_pthread.h
+++ b/include/edthreads_pthread.h
@@ -1,11 +1,11 @@
#ifndef GR_EDTHREADS_PTHREAD_H_INCLUDED
#define GR_EDTHREADS_PTHREAD_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edthreads_pthread_h,"$Id: edthreads_pthread.h,v 1.9 2019/03/15 23:03:10 cvsuser Exp $")
+__CIDENT_RCSID(gr_edthreads_pthread_h,"$Id: edthreads_pthread.h,v 1.10 2022/03/21 14:55:27 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edthreads_pthread.h,v 1.9 2019/03/15 23:03:10 cvsuser Exp $
+/* $Id: edthreads_pthread.h,v 1.10 2022/03/21 14:55:27 cvsuser Exp $
* Threads interface
* ISO/IEC 9899:201x Committee Draft
* April 12, 2011 N1570
@@ -86,7 +86,7 @@ __CPRAGMA_ONCE
* which is returned by a function to indicate that the requested operation
* failed because it was unable to allocate memory.
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edthreads_win32.h b/include/edthreads_win32.h
index ce5e595c..c26e269d 100644
--- a/include/edthreads_win32.h
+++ b/include/edthreads_win32.h
@@ -1,11 +1,11 @@
#ifndef GR_EDTHREADS_WIN32_H_INCLUDED
#define GR_EDTHREADS_WIN32_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edthreads_win32_h,"$Id: edthreads_win32.h,v 1.16 2020/06/18 12:51:29 cvsuser Exp $")
+__CIDENT_RCSID(gr_edthreads_win32_h,"$Id: edthreads_win32.h,v 1.17 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edthreads_win32.h,v 1.16 2020/06/18 12:51:29 cvsuser Exp $
+/* $Id: edthreads_win32.h,v 1.17 2022/03/21 14:55:28 cvsuser Exp $
* Threads interface
* ISO/IEC 9899:201x Committee Draft
* April 12, 2011 N1570
@@ -86,7 +86,7 @@ __CPRAGMA_ONCE
* which is returned by a function to indicate that the requested operation
* failed because it was unable to allocate memory.
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edtrace.h b/include/edtrace.h
index 980011ee..8f4eb9ac 100644
--- a/include/edtrace.h
+++ b/include/edtrace.h
@@ -1,16 +1,16 @@
#ifndef GR_EDTRACE_H_INCLUDED
#define GR_EDTRACE_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edtrace_h,"$Id: edtrace.h,v 1.28 2019/03/15 23:03:10 cvsuser Exp $")
+__CIDENT_RCSID(gr_edtrace_h,"$Id: edtrace.h,v 1.29 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edtrace.h,v 1.28 2019/03/15 23:03:10 cvsuser Exp $
+/* $Id: edtrace.h,v 1.29 2022/03/21 14:55:28 cvsuser Exp $
* trace log.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/edtypes.h b/include/edtypes.h
index 8255ab4c..44cade2e 100644
--- a/include/edtypes.h
+++ b/include/edtypes.h
@@ -1,16 +1,16 @@
#ifndef GR_EDTYPES_H_INCLUDED
#define GR_EDTYPES_H_INCLUDED
#include
-__CIDENT_RCSID(gr_edtypes_h,"$Id: edtypes.h,v 1.36 2020/04/21 21:19:41 cvsuser Exp $")
+__CIDENT_RCSID(gr_edtypes_h,"$Id: edtypes.h,v 1.39 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: edtypes.h,v 1.36 2020/04/21 21:19:41 cvsuser Exp $
+/* $Id: edtypes.h,v 1.39 2022/03/21 14:55:28 cvsuser Exp $
* Editor base types.
*
*
*
- * Copyright (c) 1998 - 2020, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
@@ -130,8 +130,8 @@ typedef unsigned long u_long;
typedef unsigned char uchar_t;
typedef unsigned int uint_t;
-typedef off_t FSIZE_t; /* Type for file/region sizes */
-typedef unsigned short KEY; /* Type for internal keystrokes */
+typedef off_t FSIZE_t; /* file/region sizes */
+typedef int32_t KEY; /* internal keystrokes */
#define LINEMAX 0x7fffffff
diff --git a/include/iniparser.h b/include/iniparser.h
index dd5b0f54..1dd44e9f 100644
--- a/include/iniparser.h
+++ b/include/iniparser.h
@@ -1,16 +1,16 @@
#ifndef GR_INIPARSER_H_INCLUDED
#define GR_INIPARSER_H_INCLUDED
#include
-__CIDENT_RCSID(gr_iniparser_h,"$Id: iniparser.h,v 1.7 2019/03/15 23:03:10 cvsuser Exp $")
+__CIDENT_RCSID(gr_iniparser_h,"$Id: iniparser.h,v 1.8 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: iniparser.h,v 1.7 2019/03/15 23:03:10 cvsuser Exp $
+/* $Id: iniparser.h,v 1.8 2022/03/21 14:55:28 cvsuser Exp $
* INI parser.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/libllist.h b/include/libllist.h
index 6d33f346..26e782a9 100644
--- a/include/libllist.h
+++ b/include/libllist.h
@@ -1,16 +1,16 @@
#ifndef GR_LIBLLIST_H_INCLUDED
#define GR_LIBLLIST_H_INCLUDED
#include
-__CIDENT_RCSID(gr_llist_h,"$Id: libllist.h,v 1.17 2019/03/15 23:03:10 cvsuser Exp $")
+__CIDENT_RCSID(gr_llist_h,"$Id: libllist.h,v 1.18 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: libllist.h,v 1.17 2019/03/15 23:03:10 cvsuser Exp $
+/* $Id: libllist.h,v 1.18 2022/03/21 14:55:28 cvsuser Exp $
* Linked list management system
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/libmisc.h b/include/libmisc.h
index da211531..651d8927 100644
--- a/include/libmisc.h
+++ b/include/libmisc.h
@@ -1,16 +1,16 @@
#ifndef GR_LIBMISC_H_INCLUDED
#define GR_LIBMISC_H_INCLUDED
#include
-__CIDENT_RCSID(gr_libmisc_h,"$Id: libmisc.h,v 1.19 2019/03/15 23:03:10 cvsuser Exp $")
+__CIDENT_RCSID(gr_libmisc_h,"$Id: libmisc.h,v 1.20 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: libmisc.h,v 1.19 2019/03/15 23:03:10 cvsuser Exp $
+/* $Id: libmisc.h,v 1.20 2022/03/21 14:55:28 cvsuser Exp $
* libmisc - Miscellaneous library functions.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/libsplay.h b/include/libsplay.h
index 65179d68..51ae4c6e 100644
--- a/include/libsplay.h
+++ b/include/libsplay.h
@@ -1,11 +1,11 @@
#ifndef GR_LIBSPLAY_H_INCLUDED
#define GR_LIBSPLAY_H_INCLUDED
#include
-__CIDENT_RCSID(gr_libsplay_h,"$Id: libsplay.h,v 1.19 2019/03/15 23:03:10 cvsuser Exp $")
+__CIDENT_RCSID(gr_libsplay_h,"$Id: libsplay.h,v 1.20 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: libsplay.h,v 1.19 2019/03/15 23:03:10 cvsuser Exp $
+/* $Id: libsplay.h,v 1.20 2022/03/21 14:55:28 cvsuser Exp $
* A SPLAY tree is a self-adjusting binary search tree with the additional property that
* recently accessed elements are quick to access again. It performs basic operations such as
* insertion, look-up and removal in O(log n) amortized time. For many sequences of non-random
@@ -23,7 +23,7 @@ __CPRAGMA_ONCE
* Reference: https://www.cs.cmu.edu/~sleator/papers/self-adjusting.pdf
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/libstr.h b/include/libstr.h
index 6e09dc0f..a7ea913b 100644
--- a/include/libstr.h
+++ b/include/libstr.h
@@ -1,16 +1,16 @@
#ifndef GR_LIBSTR_H_INCLUDED
#define GR_LIBSTR_H_INCLUDED
#include
-__CIDENT_RCSID(gr_str_h,"$Id: libstr.h,v 1.22 2019/03/15 23:03:11 cvsuser Exp $")
+__CIDENT_RCSID(gr_str_h,"$Id: libstr.h,v 1.23 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: libstr.h,v 1.22 2019/03/15 23:03:11 cvsuser Exp $
+/* $Id: libstr.h,v 1.23 2022/03/21 14:55:28 cvsuser Exp $
* libstr - String utility library.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/libtime.h b/include/libtime.h
index d9283fcf..56a7c5f9 100644
--- a/include/libtime.h
+++ b/include/libtime.h
@@ -1,16 +1,16 @@
#ifndef GR_LIBTIME_H_INCLUDED
#define GR_LIBTIME_H_INCLUDED
#include
-__CIDENT_RCSID(gr_libtime_h,"$Id: libtime.h,v 1.5 2019/03/15 23:03:11 cvsuser Exp $")
+__CIDENT_RCSID(gr_libtime_h,"$Id: libtime.h,v 1.6 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: libtime.h,v 1.5 2019/03/15 23:03:11 cvsuser Exp $
+/* $Id: libtime.h,v 1.6 2022/03/21 14:55:28 cvsuser Exp $
* libtime - Miscellaneous time library functions.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/msvcversions.h b/include/msvcversions.h
index 93daaaa5..49baacf2 100644
--- a/include/msvcversions.h
+++ b/include/msvcversions.h
@@ -1,14 +1,14 @@
#ifndef GR_MSVCVERSIONS_H_INCLUDED
#define GR_MSVCVERSIONS_H_INCLUDED
#include
-__CIDENT_RCSID(gr_msvcversions_h,"$Id: msvcversions.h,v 1.2 2020/03/26 22:55:21 cvsuser Exp $")
+__CIDENT_RCSID(gr_msvcversions_h,"$Id: msvcversions.h,v 1.3 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: msvcversions.h,v 1.2 2020/03/26 22:55:21 cvsuser Exp $
+/* $Id: msvcversions.h,v 1.3 2022/03/21 14:55:28 cvsuser Exp $
* _MSC_VER definitions
*
- * Copyright (c) 2017 - 2020, Adam Young.
+ * Copyright (c) 2017 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/patmatch.h b/include/patmatch.h
index 8b70dbb7..e42a2be8 100644
--- a/include/patmatch.h
+++ b/include/patmatch.h
@@ -1,16 +1,16 @@
#ifndef GR_PATMATCH_H_INCLUDED
#define GR_PATMATCH_H_INCLUDED
#include
-__CIDENT_RCSID(gr_patmatch_h,"$Id: patmatch.h,v 1.8 2020/03/27 18:08:15 cvsuser Exp $")
+__CIDENT_RCSID(gr_patmatch_h,"$Id: patmatch.h,v 1.9 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: patmatch.h,v 1.8 2020/03/27 18:08:15 cvsuser Exp $
+/* $Id: patmatch.h,v 1.9 2022/03/21 14:55:28 cvsuser Exp $
* Simple pattern matching.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/stable.h b/include/stable.h
index 6b4598db..e8d29cb0 100644
--- a/include/stable.h
+++ b/include/stable.h
@@ -1,11 +1,11 @@
#ifndef GR_STABLE_H_INCLUDED
#define GR_STABLE_H_INCLUDED
#include
-__CIDENT_RCSID(gr_stable_h,"$Id: stable.h,v 1.11 2019/03/15 23:03:11 cvsuser Exp $")
+__CIDENT_RCSID(gr_stable_h,"$Id: stable.h,v 1.12 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: stable.h,v 1.11 2019/03/15 23:03:11 cvsuser Exp $
+/* $Id: stable.h,v 1.12 2022/03/21 14:55:28 cvsuser Exp $
* Self-organising string hash data structure.
*
* This is a library of routines for storing a data structure where the
@@ -13,7 +13,7 @@ __CPRAGMA_ONCE
* hash using chaining to address clashes. Upon the key count exceeding the
* fill factory, the hash shall extend by doubling in size.
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/stype.h b/include/stype.h
index 37bfc940..6b72fc47 100644
--- a/include/stype.h
+++ b/include/stype.h
@@ -1,11 +1,11 @@
#ifndef GR_STYPE_H_INCLUDED
#define GR_STYPE_H_INCLUDED
#include
-__CIDENT_RCSID(gr_stype_h,"$Id: stype.h,v 1.11 2019/03/15 23:03:11 cvsuser Exp $")
+__CIDENT_RCSID(gr_stype_h,"$Id: stype.h,v 1.12 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: stype.h,v 1.11 2019/03/15 23:03:11 cvsuser Exp $
+/* $Id: stype.h,v 1.12 2022/03/21 14:55:28 cvsuser Exp $
* Self-organising integer data structure
*
* library of routines for storing a data structure where the primary key is an integer.
@@ -15,7 +15,7 @@ __CPRAGMA_ONCE
* The implementation maintains an array of integer/pointer pairs, which is sorted
* into order every when necessary; allowing access in numerical order.
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/vm_alloc.h b/include/vm_alloc.h
index eccf9736..c9032329 100644
--- a/include/vm_alloc.h
+++ b/include/vm_alloc.h
@@ -1,15 +1,15 @@
#ifndef GR_VM_ALLOC_H_INCLUDED
#define GR_VM_ALLOC_H_INCLUDED
#include
-__CIDENT_RCSID(gr_vm_alloc_h,"$Id: vm_alloc.h,v 1.12 2019/03/15 23:03:11 cvsuser Exp $")
+__CIDENT_RCSID(gr_vm_alloc_h,"$Id: vm_alloc.h,v 1.13 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: vm_alloc.h,v 1.12 2019/03/15 23:03:11 cvsuser Exp $
+/* $Id: vm_alloc.h,v 1.13 2022/03/21 14:55:28 cvsuser Exp $
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/include/vtype.h b/include/vtype.h
index db8dc5f7..d7ec0964 100644
--- a/include/vtype.h
+++ b/include/vtype.h
@@ -1,16 +1,16 @@
#ifndef GR_VTYPE_H_INCLUDED
#define GR_VTYPE_H_INCLUDED
#include
-__CIDENT_RCSID(gr_vtype_h,"$Id: vtype.h,v 1.10 2019/03/15 23:03:11 cvsuser Exp $")
+__CIDENT_RCSID(gr_vtype_h,"$Id: vtype.h,v 1.11 2022/03/21 14:55:28 cvsuser Exp $")
__CPRAGMA_ONCE
/* -*- mode: c; indent-width: 4; -*- */
-/* $Id: vtype.h,v 1.10 2019/03/15 23:03:11 cvsuser Exp $
+/* $Id: vtype.h,v 1.11 2022/03/21 14:55:28 cvsuser Exp $
* Self-organising integer vector data structure.
*
*
*
- * Copyright (c) 1998 - 2019, Adam Young.
+ * Copyright (c) 1998 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/libbsdio/.cvsignore b/libbsdio/.cvsignore
new file mode 100644
index 00000000..8c40b219
--- /dev/null
+++ b/libbsdio/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+*.err
diff --git a/libbsdio/vfprintf.c b/libbsdio/vfprintf.c
index 7e5e424f..ac1ae85e 100644
--- a/libbsdio/vfprintf.c
+++ b/libbsdio/vfprintf.c
@@ -42,9 +42,9 @@
#endif
//disabled functionality
-// USE_MBRTOWC
-// USE_MMAP
-// USE_DTOA
+// USE_MBRTOWC
+// USE_MMAP
+// USE_DTOA
#ifdef HAVE_STDARG_H
#include
diff --git a/libchartable/.cvsignore b/libchartable/.cvsignore
index ee27b282..e32c4822 100644
--- a/libchartable/.cvsignore
+++ b/libchartable/.cvsignore
@@ -1,7 +1,11 @@
Makefile
+*.err
charsetdesc.h
+charsetdict.h
charsetlocales.h
charsetnames.h
charsettables.h
+charsettable.*
cnvtables
data
+ref
diff --git a/libchartable/.gitignore b/libchartable/.gitignore
index 86ec5a1a..656b59ed 100644
--- a/libchartable/.gitignore
+++ b/libchartable/.gitignore
@@ -1,6 +1,7 @@
charsetdesc.h
+charsetdict.h
charsetlocales.h
charsetnames.h
charsettables.h
cnvtables/
-data/
\ No newline at end of file
+data/
diff --git a/libchartable/Makefile.in b/libchartable/Makefile.in
index e9612cb1..cbe8db6f 100644
--- a/libchartable/Makefile.in
+++ b/libchartable/Makefile.in
@@ -1,9 +1,9 @@
# -*- mode: mak; indent-tabs-mode: t; tab-width: 8 -*-
-# $Id: Makefile.in,v 1.24 2020/06/18 20:35:17 cvsuser Exp $
+# $Id: Makefile.in,v 1.29 2022/03/21 15:11:49 cvsuser Exp $
# libchartable makefile.
#
#
-# Copyright (c) 2010 - 2020, Adam Young.
+# Copyright (c) 2010 - 2022, Adam Young.
# All rights reserved.
#
# This file is part of the GRIEF Editor.
@@ -126,8 +126,9 @@ CTBLOBJS=\
$(D_OBJ)/charsetutf32$(O) \
$(D_OBJ)/charsetutf16$(O) \
$(D_OBJ)/charsetutf8$(O) \
- $(D_OBJ)/charsetwidth$(O) \
- $(D_OBJ)/charsetwidth_cjk$(O)
+ $(D_OBJ)/charsetwidth_cjk$(O) \
+ \
+ $(D_OBJ)/utf8$(O)
MODULES= $(notdir $(basename $(wildcard cnvtables/cx*.c)))
@@ -153,6 +154,7 @@ debug:
$(CTBLLIB): charsetlocales.h \
charsettable.c \
+ charsetdesc.h \
$(D_OBJ)/.created \
$(CTBLOBJS)
$(RM) $(RMFLAGS) $@
@@ -170,7 +172,7 @@ charsetlocales.h: makelocale.pl
charsettable.c: charsettables.h
-charsettables.h: makechartable.pl cnvtables/.created
+charsetdesc.h charsettables.h: makechartable.pl cnvtables/.created
@echo building character tables
$(PERL) makechartable.pl --crunch --dynamic --packaged
@@ -182,12 +184,11 @@ data/.import: data/.created \
data/MAPPINGS/.import \
data/Unihan.zip \
data/UCD.zip \
- data/uniset.tar.gz \
- data/Zeichenreferenz
+ data/uniset.tar.gz
@echo "++ do not delete, managed content ++" > $@
data/MAPPINGS/.import: data/MAPPINGS/.created
- $(WGET) -P data -r -nv -nH -e robots=off --cut-dirs=1 --no-parent --reject "index.html.*" http://ftp.unicode.org/Public/MAPPINGS/
+ $(WGET) -P data -r -nv -nH -e robots=off --cut-dirs=1 --no-parent --reject "index.html?*" http://ftp.unicode.org/Public/MAPPINGS/
@echo "++ do not delete, managed content ++" > $@
data/Unihan.zip:
diff --git a/libchartable/charsetalias.c b/libchartable/charsetalias.c
index 4a918c63..3d4704a5 100644
--- a/libchartable/charsetalias.c
+++ b/libchartable/charsetalias.c
@@ -1,11 +1,11 @@
#include
-__CIDENT_RCSID(gr_charsetalias_c,"$Id: charsetalias.c,v 1.13 2020/06/18 13:10:35 cvsuser Exp $")
+__CIDENT_RCSID(gr_charsetalias_c,"$Id: charsetalias.c,v 1.14 2022/03/21 14:59:57 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
/* Locale/multibyte character information.
*
*
- * Copyright (c) 2010 - 2018, Adam Young.
+ * Copyright (c) 2010 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/libchartable/charsetcurrent.c b/libchartable/charsetcurrent.c
index a81a82c8..03f269e6 100644
--- a/libchartable/charsetcurrent.c
+++ b/libchartable/charsetcurrent.c
@@ -1,11 +1,11 @@
#include
-__CIDENT_RCSID(gr_charsetcurrent_c,"$Id: charsetcurrent.c,v 1.9 2020/06/18 13:10:35 cvsuser Exp $")
+__CIDENT_RCSID(gr_charsetcurrent_c,"$Id: charsetcurrent.c,v 1.10 2022/03/21 14:59:57 cvsuser Exp $")
/* -*- mode: c; indent-width: 4; -*- */
/* libcharset current.
*
*
- * Copyright (c) 2010 - 2018, Adam Young.
+ * Copyright (c) 2010 - 2022, Adam Young.
* All rights reserved.
*
* This file is part of the GRIEF Editor.
diff --git a/libchartable/charsetfstream.c b/libchartable/charsetfstream.c
index c536f0a1..e41b80ef 100644
--- a/libchartable/charsetfstream.c
+++ b/libchartable/charsetfstream.c
@@ -1,11 +1,11 @@
#include