Age | Commit message (Collapse) | Author | Files | Lines |
|
teco-gtk-label.gob to plain C
* Using modern GObject idioms and macros greatly reduces the necessary boilerplate code.
* The plain C versions of our GObject classes are now "final" (cannot be derived)
This means we can hide the instance structures from the headers and avoid using
explicit private fields.
* Avoids some deprecation warnings when building the Gtk UI.
* GOB2 is apparently no longer maintained, so this seems like a good idea in the long run.
* The most important reason however is that there is no precompiled GOB2 for Windows
which prevents compilation on native Windows hosts, eg. during nightly builds.
This is even more important as Gtk+3 is distributed on Windows practically
exclusively via MSYS.
(ArchLinux contains MinGW gtk3 packages as well, so cross-compiling from ArchLinux
would have been an alternative.)
|
|
"optimized" code-path on UNIX
|
|
* Turned out to be useful in debugging the "Memory limiting during spawning" test case
on Windows.
* Use UNIX shell emulation (0,128ED) in all test cases.
Should be necessary in order to run the testsuite on Windows, but
it is currently broken anyway.
* avoid <EG> when preprocessing files - use GNU Make's $(shell) instead
* Fixes builds on MinGW where there are still problems with <EC> and <EG>
at least in the virtual build environment.
* Results in a another automake warning about non-POSIX Make constructs.
This is not critical since we depend on GNU Make anyway.
|
|
* Environment variables are case insensitive on Windows
while SciTECO variables are case sensitive.
We must therefore make sure that we first unset any $COMSPEC or $ComSpec
from the environment before resetting it, thereby fixing its case.
* Fixes command execution via <EC> on systems where the variable
was not called $ComSpec.
|
|
(<S>) for multiplication overflows
* Since the numbers come from "outside" (SciTECO scripts) this is easily possible,
resulting either in missed checks or even memory corruption.
* In particular, this fixes the "Searching with large counts" test case on 32-bit builds.
Perhaps at least one CI build should be 32-bit?
|
|
* this flag could negatively affect optimizations
* fixes builds on MinGW
|
|
don't build an empty libdlmalloc
* on some platforms (eg. Darwin/mac OS) we cannot apparently build empty
convenience libraries
* instead, we use conditional subdirectories and a conditional library dependency
|
|
* I could not get malloc replacement via dlmalloc to work.
This does not work like on Linux by overwriting weak malloc() functions.
It should theoretically be possible to overwrite the default malloc zone
but I could not properly debug this since I can only build for Mac OS
via CI.
* memory polling seems to work though - test suite runs through
and it includes memory limiting test cases.
|
|
would be exceeded
* Checking whether the allocation succeeded may not prevent exceeding the memory
limit excessively.
* Even if the memory limit is not exceeded, the allocation can fail theoretically
and the program would terminate abnormally.
This however is true for all allocations in SciTECO (via glib).
* teco_memory_check() therefore now supports checking whether an allocation would
exceed the memory limit which will be useful before very large or variable allocations
in addition to the regular checking in teco_machine_main_step().
* As a sideeffect, this fixes the "Searching with large counts" test case on Mac OS
where too large allocations were not detected as expected (apparently Mac OS
happily gives out ridiculously large chunks of memory).
Now, all platforms are guaranteed to have the same behaviour.
|
|
NOTE: Aliases and weak symbols must not be used for portability reasons!
|
|
file systems
* There is a "Scintilla.h" as well.
* should fix macOS and builds on native Windows hosts
* It wasn't practical to refer to the Scintilla includes using paths since
the Scintilla location is configurable (--with-scintilla).
So we'd have to write something like #include <include/Scintilla.h>.
For Scinterm we cannot avoid collisions neither as its path is also
configurable (--with-scinterm).
Effectively, we must prevent name clashes across SciTECO and all
of Scintilla and Scinterm.
|
|
This is a total conversion of SciTECO to plain C (GNU C11).
The chance was taken to improve a lot of internal datastructures,
fix fundamental bugs and lay the foundations of future features.
The GTK user interface is now in an useable state!
All changes have been squashed together.
The language itself has almost not changed at all, except for:
* Detection of string terminators (usually Escape) now takes
the string building characters into account.
A string is only terminated outside of string building characters.
In other words, you can now for instance write
I^EQ[Hello$world]$
This removes one of the last bits of shellisms which is out of
place in SciTECO where no tokenization/lexing is performed.
Consequently, the current termination character can also be
escaped using ^Q/^R.
This is used by auto completions to make sure that strings
are inserted verbatim and without unwanted sideeffects.
* All strings can now safely contain null-characters
(see also: 8-bit cleanliness).
The null-character itself (^@) is not (yet) a valid SciTECO
command, though.
An incomplete list of changes:
* We got rid of the BSD headers for RB trees and lists/queues.
The problem with them was that they used a form of metaprogramming
only to gain a bit of type safety. It also resulted in less
readble code. This was a C++ desease.
The new code avoids metaprogramming only to gain type safety.
The BSD tree.h has been replaced by rb3ptr by Jens Stimpfle
(https://github.com/jstimpfle/rb3ptr).
This implementation is also more memory efficient than BSD's.
The BSD list.h and queue.h has been replaced with a custom
src/list.h.
* Fixed crashes, performance issues and compatibility issues with
the Gtk 3 User Interface.
It is now more or less ready for general use.
The GDK lock is no longer used to avoid using deprecated functions.
On the downside, the new implementation (driving the Gtk event loop
stepwise) is even slower than the old one.
A few glitches remain (see TODO), but it is hoped that they will
be resolved by the Scintilla update which will be performed soon.
* A lot of program units have been split up, so they are shorter
and easier to maintain: core-commands.c, qreg-commands.c,
goto-commands.c, file-utils.h.
* Parser states are simply structs of callbacks now.
They still use a kind of polymorphy using a preprocessor trick.
TECO_DEFINE_STATE() takes an initializer list that will be
merged with the default list of field initializers.
To "subclass" states, you can simply define new macros that add
initializers to existing macros.
* Parsers no longer have a "transitions" table but the input_cb()
may use switch-case statements.
There are also teco_machine_main_transition_t now which can
be used to implement simple transitions. Additionally, you
can specify functions to execute during transitions.
This largely avoids long switch-case-statements.
* Parsers are embeddable/reusable now, at least in parse-only mode.
This does not currently bring any advantages but may later
be used to write a Scintilla lexer for TECO syntax highlighting.
Once parsers are fully embeddable, it will also be possible
to run TECO macros in a kind of coroutine which would allow
them to process string arguments in real time.
* undo.[ch] still uses metaprogramming extensively but via
the C preprocessor of course. On the downside, most undo
token generators must be initiated explicitly (theoretically
we could have used embedded functions / trampolines to
instantiate automatically but this has turned out to be
dangereous).
There is a TECO_DEFINE_UNDO_CALL() to generate closures for
arbitrary functions now (ie. to call an arbitrary function
at undo-time). This simplified a lot of code and is much
shorter than manually pushing undo tokens in many cases.
* Instead of the ridiculous C++ Curiously Recurring Template
Pattern to achieve static polymorphy for user interface
implementations, we now simply declare all functions to
implement in interface.h and link in the implementations.
This is possible since we no longer hace to define
interface subclasses (all state is static variables in
the interface's *.c files).
* Headers are now significantly shorter than in C++ since
we can often hide more of our "class" implementations.
* Memory counting is based on dlmalloc for most platforms now.
Unfortunately, there is no malloc implementation that
provides an efficient constant-time memory counter that
is guaranteed to decrease when freeing memory.
But since we use a defined malloc implementation now,
malloc_usable_size() can be used safely for tracking memory use.
malloc() replacement is very tricky on Windows, so we
use a poll thread on Windows. This can also be enabled
on other supported platforms using --disable-malloc-replacement.
All in all, I'm still not pleased with the state of memory
limiting. It is a mess.
* Error handling uses GError now. This has the advantage that
the GError codes can be reused once we support error catching
in the SciTECO language.
* Added a few more test suite cases.
* Haiku is no longer supported as builds are instable and
I did not manage to debug them - quite possibly Haiku bugs
were responsible.
* Glib v2.44 or later are now required.
The GTK UI requires Gtk+ v3.12 or later now.
The GtkFlowBox fallback and sciteco-wrapper workaround are
no longer required.
* We now extensively use the GCC/Clang-specific g_auto
feature (automatic deallocations when leaving the current
code block).
* Updated copyright to 2021.
SciTECO has been in continuous development, even though there
have been no commits since 2018.
* Since these changes are so significant, the target release has
been set to v2.0.
It is planned that beginning with v3.0, the language will be
kept stable.
|
|
detect EMCurses
* Emscripten can be used (theoretically) to build a host-only platform-independant version
of SciTECO (running under node.js instead of the browser).
* I ported netbsd-curses with Emscripten for that purpose. Therefore, adaptions for running
in the browser are restricted to EMcurses now.
|
|
* Array allocations were not properly accounted since the compiler
would call the replacement new() which assumes that it would
always be called along with the replacement sized-deletion.
This is not true for array new[] allocations resulting in
a constant increase of memory_usage and unrecoverable situations.
This problem however could be fixed in principle by avoiding
memory counting for arrays or falling back to malloc_usable_size.
* The bigger problem was that some STLs (new_allocator) are broken, calling the
non-sized delete for regular new() calls which could in principle
be matched by sized-delete.
This is also the reason why I had to provide a non-sized
delete replacement, which in reality intoduced memory leaks.
* Since adding checks for the broken compiler versions or a configure-time
check that tries to detect these broken systems seems tedious,
I simply removed that optimization.
* This means we always have to rely on malloc_usable_size() now
for non-SciTECO-object memory measurement.
* Perhaps in the future, there should be an option for allowing
portable measurement at the cost of memory usage, by prefixing
each memory chunk with the chunk size.
Maintainers could then decide to optimize their build for "speed"
at the cost of memory overhead.
* Another solution to this non-ending odyssey might be to introduce
our own allocator, replacing malloc(), and allowing our own
precise measurements.
|
|
* it turned out to be possible to provoke memory_usage
overflows or underruns, resulting in unrecoverable states
* a possible reason can be that at least with G++ 5.4.0,
the compiler would sometimes call the (default) non-sized
delete followed by our custom sized delete/deallocator.
* This was true even after compiling Scintilla with -fsized-deallocation.
* therefore we provide an empty non-sized delete now.
* memory_usage counting can now be debugged by uncommenting
DEBUG_MAGIC in memory.cpp. This uses a magic value to detect
instrumented allocations being mixed with non-instrumented
allocations.
* simplified the global sized-deallocation functions
(they are identical to the Object-class allocators).
|
|
Automakefiles could be simplified by updating CXXFLAGS
in configure.ac instead.
|
|
* avoid warnings
* make sure Doxygen finds RBEntryOwnString
* it would be nice to strip the top level `SciTECO` namespace
but this is not supported without some macro magic that
ommit the namespace declaration when processing with
Doxygen.
|
|
* when enabled, it will automatically upper-case all
one or two letter commands (which are case insensitive).
* also affects the up-carret control commands, so they when inserted
they look more like real control commands.
* specifically does not affect case-insensitive Q-Register specifications
* the result are command lines that are better readable and conform
to the coding style used in SciTECO's standard library.
This eases reusing command lines as well.
* Consequently, string-building and pattern match characters should
be case-folded as well, but they aren't currently since
State::process_edit_cmd() does not have sufficient insight
into the MicroStateMachines. Also, it could not be delegated
to the MicroStateMachines.
Perhaps they should be abandoned in favour of embeddedable
regular state machines; or regular state machines with a stack
of return states?
|
|
* this resulted in assertions (crashes!) for harmless typos like "+23="
* a test case has been added
|
|
* test case: HECcat$ on a large buffer (>= 64kb)
truncates the buffer or repeats its beginning
* it turns out that the incremental writing to the process' stdin
was broken. We were always writing data from the beginning of the buffer
which fails if the stdin watcher must be activated more than once.
* Also, EOLWriter::convert() can validly return 0, even if bytes have
been written on the data sink, so this value cannot be used to
check whether the process has closed its stdin.
We now make sure that the entire buffer range is written to stdin.
* Piping large buffers no longer removes the buffer gap.
This makes little difference when filtering via EC since
it will change the buffer gap anyway.
Can make a huge difference when not touching the buffer, though
(e.g. HEGAcat$).
* I did not add a test suite case since that requires
a very large test file and it cannot be easily generated automatically.
|
|
* StateQueryQReg is now derived from StateExpectQReg
whose semantics have been changed slightly.
* The alternative would have been another common base class for both
StateQueryQReg and StateExpectQReg.
|
|
support
* Since netbsd-curses can act as a drop-in replacement to ncurses,
SciTECO builds with --with-interface=ncurses as well.
However, it is unintuitive for users to build with ncurses support
when actually linking against netbsd-curses; so another option has been added.
* The UNIX/TTY specific code (which works with both ncurses and netbsd-curses)
was selected when NCURSES was detected at build-time.
This does not work for netbsd-curses, so we define a new symbol
NETBSD_CURSES. At build-time, a CURSES_TTY macro may now be defined.
* This effectively fixes the stdio in interactive mode, window titles
and the XTerm clipboard support for netbsd-curses.
Some minor features like the reduced ESCDELAY are still broken.
|
|
been shown to be unacceptably broken, so the fallback implementation has been improved
* mallinfo() is not only broken on 64-bit systems but slows things
down linearilly to the memory size of the process.
E.g. after 500000<%A>, SciTECO will act sluggish! Shutting down
afterwards can take minutes...
mallinfo() was thus finally discarded as a memory measurement
technique.
* Evaluating /proc/self/statm? has also been evaluated and discarded
because doing this frequently is even slower.
* Instead, the fallback implementation has been drastically improved:
* If possible use C++14 global sized deallocators, allowing memory measurements
across the entire C++ code base with minimal runtime overhead.
Since we only depend on C++11, a lengthy Autoconf check had to be introduced.
* Use malloc_usable_size() with global non-sized deallocators to
measure the approx. memory usage of the entire process (at least
the ones done via C++).
The cheaper C++11 sized deallocators implemented via SciTECO::Object still
have precedence, so this affects Scintilla code only.
* With both improvements the test case
sciteco -e '<@EU[X^E\a]"^E\a"%a>'
is handled sufficiently well now on glibc and performance is much better
now.
* The jemalloc-specific technique has been removed since it no longer
brings any benefits compared to the improved fallback technique.
Even the case of using malloc_usable_size() in strict C++ mode is
up to 3 times faster.
* The new fallback implementation might actually be good enough for
Windows as well if some MSVCRT-specific support is added, like
using _msize() instead of malloc_usable_size().
This must be tested and benchmarked, so we keep the Windows-specific
implementation for the time being.
|
|
* in a flat list of undo tokens, we need to store
the program counter (ie. command line position)
that the undo token corresponds to.
Since in general there is more than one undo token per
input character, this stored PCs redundantly.
* For input characters with no undo tokens
(only applies to NOPs like space in the command line
macro), this needs one more pointer than before.
* In case of 1 undo token per input character,
the new implementation uses approx. the same memory.
* In the most common case of more than one undo token
per input character, this saves at least 4 bytes per
undo token.
* In large macros and long loops the effect is especially
pronounced. E.g. 500000<%A> will use 8MB less memory
with the new implementation.
|
|
editing key
* StateEscape should return the same fnmacro mask as StateStart
* When rubbing out a command, we should stop at StateEscape as well.
Therefore we reintroduced States::is_start().
RTTI is still not used.
|
|
as State::process_edit_cmd() virtual methods
* Cmdline::process_edit_cmd() was much too long and deeply nested.
It used RTTI excessively to implement the state-specific behaviour.
It became apparent that the behaviour is largely state-specific and could be
modelled much more elegantly as virtual methods of State.
* Basically, a state can now implement a method to customize its
commandline behaviour.
In the case that the state does not define custom behaviour for
the key pressed, it can "chain" to the parent class' process_edit_cmd().
This can be optimized to tail calls by the compiler.
* The State::process_edit_cmd() implementations are still isolated in
cmdline.cpp. This is not strictly necessary but allows us keep the
already large compilations units like parser.cpp small.
Also, the edit command processing has little to do with the rest of
a state's functionality and is only used in interactive mode.
* As a result, we have many small functions now which are much easier to
maintain.
This makes adding new and more complex context sensitive editing behaviour
easier.
* State-specific function key masking has been refactored by introducing
State::get_fnmacro_mask().
* This allowed us to remove the States::is_*() functions which have
always been a crutch to support context-sensitive key handling.
* RTTI is almost completely eradicated, except for exception handling
and StdError(). Both remaining cases can probably be avoided in the
future, allowing us to compile smaller binaries.
|
|
and added a FreeBSD/jemalloc-specific implementation
* largely reverts 39cfc573, but leaves in minor and documentation
changes.
* further experimentation of memory limiting using malloc() wrapping
has shown additional problems, like dlsym() calling malloc-functions,
further reducing the implementation to glibc-specific means.
This means there had been no implementation for FreeBSD and checks
would have to rely on undocumented internal implementation details
of different libcs, which is not a good thing.
* Other problems have been identified, like having to wrap calloc(),
guarding against underruns and multi-thread safety had been identified
but could be worked around.
* A technique by calculating the memory usage as sbrk(0) - &end
has been shown to be effective enough, at least on glibc.
However even on glibc it has shortcomings since malloc() will
somtimes use mmap() for allocations and the technique
relies on implementation details of the libc.
Furthermore another malloc_trim(0) had to be added to the error
recovery in interactive mode, since glibc does not adjust the program break
automatically (to avoid syscalls I presume).
* On FreeBSD/jemalloc, the sbrk(0) method totally fails because jemalloc
exclusively allocates via mmap() -> that solution was discarded as well.
* Since all evaluated techniques turn out to be highly platform
specific, I reverted to the simple and stable platform-specific
mallinfo() API on Linux.
* On FreeBSD/jemalloc, it's possible to use mallctl("stats.allocated")
for the same purpose - so it works there, too now.
It's slower than the other techniques, though.
* A lengthy discussion has been added to memory.cpp, so that we
do not repeat the previous mistakes.
|
|
* shouldn't make much of a difference, since we're in deep trouble
when they return NULL, but the wrappers should be transparent
instead of crashing in malloc_usable_size().
|
|
portable and faster hack
* Works by "hooking" into malloc() and friends and counting the
usable heap object sizes with malloc_usable_size().
Thus, it has no memory-overhead.
* Will work at least on Linux and (Free)BSD.
Other UNIXoid systems may work as well - this is tested by ./configure.
* Usually faster than even the fallback implementation since the
memory limit is hit earlier.
* A similar approach could be tried on Windows (TODO).
* A proper memory-limiting counting all malloc()s in the system can make
a huge difference as this test case shows:
sciteco -e '<@EU[X^E\a]"^E\a"%a>'
It will allocate gigabytes before hitting the 500MB memory limit...
* Fixed the UNIX-function checks on BSDs.
|
|
|
|
* especially to improve building on FreeBSD 11
* We need GNU Make, yet alone because Scintilla/Scinterm
needs it. We now document that dependency and added
an Autoconf check from the autoconf-archive.
We make sure that the build process is invoked with GNU make
by generating only GNUmakefiles.
The Makefile.am files have not been renamed, so this
change can be rolled back easily.
* Some GNU-Make-specific autoreconf warnings have still been
resolved. But not all of them, as this would have been
unelegant and we need GNU Make anyway.
* Declare ACLOCAL_AMFLAGS to appease autoreconf
* Added an explicit check for C++11 from the autoconf-archives.
In general we should support building with every C++11 compiler
that is sufficiently GNU-like.
* Do not use `sed` for inplace editing, as different sed-implementations
have mutually incompatible syntax for this.
Instead of declaring and checking a dependency on GNU sed,
we simply use SciTECO for the editing task.
This improves code portability on BSDs.
* Similarily, BSD/POSIX `cmp` is supported now.
This fixes the test suite on BSD without declaring a
dependency on the GNU coreutils.
* Simplified sciteco-wrapper generation.
|
|
* some classic TECOs have this
* just like ^[, dollar works as a command only, not as a string terminator
* it improves the readability of macros using printable characters only
* it closes a gap in the language by allowing $$ (double-dollar) and
^[$ as printable ways to write the return from macro command.
^[^[ was not and is not possible.
* since command line termination is a regular interactive return-command
in SciTECO, double-dollar will also terminate the command line now.
This will be allowed unless it turns out to be a cause of trouble.
* The handling of unterminated commands has been cleaned up by
introducing State::end_of_macro().
Most commands (and thus states) except the start state cannot be
valid at the end of a macro since this indicates an unterminated/incomplete
command.
All lookahead-commands (currently only ^[) will end implicitly
at the end of a macro and so will need a way to perform their action.
The virtual method allows these actions to be defined with the rest
of the state's implementation.
|
|
* The $$ would leave the current state pointing to the "escape" state
which was manually fixed up in macro return handling but not in command line
return (ie. termination) handling.
Therefore the initial state at the start of the command line after $$
was the "escape" state.
The rubout-last-command immediate editing command would consequently
end up in an infinite loop trying to reach the start state.
* This has been fixed by setting the state before throwing Return().
Some additional paranoia assertions have been added to prevent this
bug in the future.
|
|
* this has been broken since cb5e08b40d
|
|
* a table reference was stored in the UndoToken.
* since there are only two tables at a given moment, this can
be avoided by having two different undo tokens, one for globals
and one for locals.
* Practically, undo tokens for locals are only created for the
top-level local Q-Reg table since macro calls with locals
with set must_undo to false since the local table is destroyed
with the macro return.
|
|
* shouldn't really be an issue but since we already have
CTL_KEY_ESC_STR as a character literal, we may as well use it.
|
|
* on MSVCRT/MinGW, space allocated with alloca()/g_newa() was apparently
freed once the first exception was caught.
This prevented the proper destruction of local Q-Reg tables and
broke the Windows port.
* Since all alternatives to alloca() like VLAs are not practical,
the default Q-Register initialization has been moved out of the
QRegisterTable constructor into QRegisterTable::insert_defaults().
* The remaining QRegisterTable initialization and destruction is
very cheap, so we simply reserve an empty QRegisterTable for
local registers on every Execute::macro() call.
The default registers are only initialized when required, though.
* All of this has to change anyway once we replace the
C++ call-stack approach to macro calls with our own macro
call frame memory management.
|
|
* we can use root() instead of min() which is faster
|
|
performance issues with memory measurements
* Fixed build problems on Windows
* g_slice on Windows has been shown to be of little use either
and it does not work well with the GetProcessMemoryInfo()
measurements.
Also, it brings the same problem as on Glibc: Not even command-line
termination returns the memory to the OS.
Therefore, we don't use g_slice at all and commented on it.
* The custom Linux and Windows memory measurement approaches
have been shown to be inefficient.
As a workaround, scripts disable memory limiting.
* A better approach -- but it will only work on Glibc -- might
be to hook into malloc(), realloc() and free() globally
and use the malloc_usable_size() of a heap object for
memory measurements. This will be relatively precise and cheap.
* We still need the "Object" base class in order to measure
memory usage as a fallback approach.
|
|
* a simple cast was missing due to C++ aliasing rules
|
|
* we were basing the glib allocators on throwing std::bad_alloc just like
the C++ operators. However, this always was unsafe since we were throwing
exceptions across plain-C frames (Glib).
Also, the memory vtable has been deprecated in Glib, resulting in
ugly warnings.
* Instead, we now let the C++ new/delete operators work like Glib
by basing them on g_malloc/g_slice.
This means they will assert and the application will terminate
abnormally in case of OOM. OOMs cannot be handled properly anyway, so it is
more important to have a good memory limiting mechanism.
* Memory limiting has been completely revised.
Instead of approximating undo stack sizes using virtual methods
(which is unprecise and comes with a performance penalty),
we now use a common base class SciTECO::Object to count the memory
required by all objects allocated within SciTECO.
This is less precise than using global replacement new/deletes
which would allow us to control allocations in all C++ code including
Scintilla, but they are only supported as of C++14 (GCC 5) and adding compile-time
checks would be cumbersome.
In any case, we're missing Glib allocations (esp. strings).
* As a platform-specific extension, on Linux/glibc we use mallinfo()
to count the exact memory usage of the process.
On Windows, we use GetProcessMemoryInfo() -- the latter implementation
is currently UNTESTED.
* We use g_malloc() for new/delete operators when there is
malloc_trim() since g_slice does not free heap chunks properly
(probably does its own mmap()ing), rendering malloc_trim() ineffective.
We've also benchmarked g_slice on Linux/glib (malloc_trim() shouldn't
be available elsewhere) and found that it brings no significant
performance benefit.
On all other platforms, we use g_slice since it is assumed
that it at least does not hurt.
The new g_slice based allocators should be tested on MSVCRT
since I assume that they bring a significant performance benefit
on Windows.
* Memory limiting does now work in batch mode as well and is still
enabled by default.
* The old UndoTokenWithSize CRTP hack could be removed.
UndoStack operations should be a bit faster now.
But on the other hand, there will be an overhead due to repeated
memory limit checking on every processed character.
|
|
* test case: rubout 1U[foo]
* this probably also leaked memory if it didn't crash
* a missing cast from RBTree::remove() was missing.
This cast is necessary since QRegister uses multiple inheritance.
The offset of RBEntryString might not be 0 in QRegister.
Also, since the base class is no longer virtual, a cast to the
virtual QRegister class is necessary to ensure that subclass
destructors get called.
This might have not caused problems before since RBEntry was virtual
or the compiler just happened to reorder the instance structures.
|
|
implementation classes
* whenever the implementation class was not exactly RBEntryType,
it had to have a virtual destructor since RBTree cared about
cleanup and had to delete its members.
* Since it does not allocate them, it is consistent to remove RBTree::clear().
The destructor now only checks that subclasses have cleaned up.
Implementing cleanup in the subclasses is trivial.
* Consequently, RBEntryString no longer has to be virtual.
HelpIndex and GotoTables are completely non-virtual now
which saves memory (and a bit of cleanup speed).
For QRegister, not much changes, though.
|
|
* From what the documentation says, a dot may only be used
once to introduce a local Q-Register specification.
The parser was accepting arbitrarily many dots though.
* Now, ".." will refer to the local register ".".
|
|
* Using a common implementation in RBTreeString::auto_complete().
This is very efficient even for very huge tables since only
an O(log(n)) lookup is required and then all entries with a matching
prefix are iterated. Worst-case complexity is still O(n), since all
entries may be legitimate completions.
If necessary, the number of matching entries could be restricted, though.
* Auto completes short and long Q-Reg names.
Short names are "case-insensitive" (since they are upper-cased).
Long specs are terminated with a closing bracket.
* Long spec completions may have problems with names containing
funny characters since they may be misinterpreted as string building
characters or contain braces. All the auto-completions suffered from
this problem already (see TODO).
* This greatly simplifies investigating the Q-Register name spaces
interactively and e.g. calling macros with long names, inserting
environment registers etc.
* Goto labels are terminated with commas since they may be part
of a computed goto.
* Help topics are matched case insensitive (just like the topic
lookup itself) and are terminated with the escape character.
This greatly simplifies navigating womanpages and looking up
topics with long names.
|
|
* the old implementation tried to avoid template programming by
making the entry comparison function virtual.
* The new RBTree implementation takes a template argument with the
implementation of RBEntry. It is now partially conventional
that the template argument must be actually derived from RBTree::RBEntry
and must define a "compare" method.
* As an advantage we now get static polymorphism (avoiding virtual
calls and allowing for more compiler optimizations) and the
the RBEntry implementation no longer has to be virtual.
* The only RB-Trees actually used are string-keyed, though.
Therefore there's a common base class RBTreeString now which
defines two synonymous "key" and "name" attributes.
* The entry base class RBEntryString is virtual again because
we do not want to propagate the RBEntryType template parameter
even further and the RBTree base class needs to destroy
entries.
This might be avoided by not defining a RBTree::clear() method,
leaving this task to the implementations.
At least QRegisters have to be virtual, though.
* RBTreeString only depends on the strcmp() and strncmp() functions
used now and only case-sensitive and case-insensitive versions
are actually required, so we instantiate these templates statically
in rbtree.cpp.
This means there are still only two instantiations of the RBTree
in the binary.
* RBTreeString defines convenient wrappers for find() and nfind()
to look up by string.
This uses the RBEntryString base class, so no allocations whatsover
are required for lookups and less space is wasted on the call stack.
* A RBEntryOwnString base class is also provided which frees the
implementations from memory managing the tree keys.
* RBTreeString can now be used to add other common functionality
like auto-completions for Q-Registers, goto labels and help topics.
* some minor optimizations
* updated TODO
|
|
called tedoc.tes
* some code simplifications
* it now supports command line arguments via getopt.tes.
* the -C flag enabled C/C++ mode.
By default tedoc parses SciTECO code which means it can be used
to document macro packages as well.
* Therefore it is installed as a separate tool now.
It may be used as a Groff preprocessor for third-party macro
authors to generate (wo)man pages.
* there's a man page tedoc.tes(1)
* The troff placeholder macro is now called ".TEDOC".
* Help topics can now be specified after the starting comment /*$ or !*$.
Topics have been defined for all built-in commands.
|
|
* this uses an optstring compatible with getopt(3).
* It does not use repeated getopt calls to iterate options, though
but places the results in registers beginning with "getopt.".
E.g. option "C" will result in "getopt.C" being set after the
call to setopt.
String arguments are supported and are placed in the string part
of the getopt registers.
* The grosciteco.tes and symbols-extract.tes scripts make use of
getopt now, to simplify and clean up their command line handling.
|
|
* it turns out that option-like arguments could not be reliably passed to
SciTECO scripts for two reasons:
a) "--" arguments are not removed from argv by GOption if it detects
and following option-like argument.
"--" would thus be passed as a script argument which will disable
option parsing in scripts that interpret "--".
b) A script run via the Hash-Bang line "#!...sciteco -m" would
require an explicit "--" to turn of GOption parsing.
However it is __impossible__ to insert after the script file name
on UNIX.
* Therefore, SciTECO now removes leading "--" arguments left over by GOption.
* If possible (Glib >= 2.44), option parsing is performed in strict POSIX
mode which inhibits parsing after the first non-option argument.
This reduces the number of cases where an explicit "--" is required.
* --mung no longer takes an argument. Instead, the first non-option argument
is expected to be the script file name.
This looks weird at first but is more consistent with how other interpeters
work. Once we revise argument passing to scripts, the script name can also
be passed to the script which is more consistent with it being the first
non-option argument.
Also, with strict POSIX parsing, this fixed Hash-Bang lines since
the script file name constructed by the kernel will automatically switch
off option parsing, passing all option-like script arguments uninterpreted
to the script.
* Since we're supporting Glib < 2.44, the Hash-Bang lines are still broken
for certain builds.
Therefore, a wrapper script is installed to libexecdir (it never has to be
executed by users and Hash-Bang lines need absolute paths anyway) which
transparently inserts "--" into the SciTECO command line and should be used
as the interpreter in portable SciTECO scripts.
The wrapper script is generated and points to the exact SciTECO binary
installed. This is important when doing parallel installs of Curses and Gtk
binaries since each one will get its own working wrapper script.
The wrapper-script workaround can be removed once we depend on Glib >= 2.44
(some day...).
* The default /usr/bin/env Hash-Bang lines are no longer used in the
scripts since they are broken anyway (UNIX incl. Linux cannot pass
multiple arguments to the interpreter!).
Scripts that get installed will get a fixed-up Hash-Bang line referring
to the installed SciTECO binary anyway.
* Interface::main() has been renamed to Interface::init() and is optional
now. The Interface::main() method was introduced because of the misconception
that interfaces will find their options in the argv array and have to do
their own parsing.
This is wrong, since their option group already cares about parsing.
Therefore, gtk_init() does not have to called explicitly, too.
|
|
* the new "?" (help) command can be used to look up
help topics.
* help topics are index from $SCITECOPATH/women/*.woman.tec
files.
* looking up a help topic opens the corresponding "womanpage"
and jumps to the position of the topic (it acts like an anchor
into the document).
* styling is performed by *.woman.tec files.
* Setting up the Scintilla view and munging the *.tec file
is performed by the new "woman.tes" lexer.
On supporting UIs (Gtk), womanpages are shown in a variable-width
font.
* Woman pages are usually not hand-written, but generated from manpages.
A special Groff post-processor grosciteco has been introduced for this
purpose. It is much like grotty, but can output SciTECO macros for styling
the document (ie. the *.woman.tec files).
It is documented in its own man-page.
* grosciteco also introduces sciteco.tmac - special Troff macros
for controlling the formatting of the document in SciTECO.
It also defines .SCITECO_TOPIC which can be used to mark up
help topics/terms in Troff markup.
* Woman pages are generated/formatted by grosciteco at compile-time, so
they will work on platforms without Groff (ie. as on windows).
* Groff has been added as a hard compile-time requirement.
* The sciteco(1) and sciteco(7) man pages have been augmented with
help topic anchors.
|