Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
empty labels are ignored
* This has long been a TECO-11 incompatibility.
* The first label in a list has index 0, i.e. `1Ofoo,bar$` jumps to label `!bar!`.
Consequently 0 is also implied, so `Olabel$` continues to do what you expect.
* `0Ofoo$` was previously also jumping to `!foo!` which was inconsistent:
All invalid indexes should do nothing, i.e. execution continues after the go-to command.
* Fixed handling of empty labels as in `1Ofoo,,bar$` - execution should also continue
after the command.
This eases writing "default" clauses immediately after the go-to.
* The ED hook values now also begin at 0, so most existing ED hook macros should
continue to work.
* Similarily, the mouse events returned by -EJ also begin at 0 now,
so fnkeys.tes continues to work as expected.
* It's still very possible of course that this breaks existing code.
|
|
support the append operation (:Xq, :^Uq...)
Works via a default implementation in the "external" Q-register "class"
by first querying the string, appending and re-setting it.
|
|
* `static const char *p = "FOO"` is not a true constant since
the variable p can still be changed.
It has to be declared as `static const char *const p = "FOO"`,
so that the pointer itself is constant.
* In case of string constants, it's easier however to use `static const char p[] = "FOO"`.
|
|
* `[q]~` was broken and resulted in crashes since it reset the clipboard character to 0.
In fact, if we don't want to break the `[a]b` idiom we cannot use the numeric cell
of register `~`.
* Therefore we no longer use the numeric part of register `~`.
Once the clipboard registers are initialized they completely replace
any existing register with the same name that may have been
set in the profile.
So we still don't leak any memory.
(But perhaps it would now be better to fail with an error
if one of the clipboard registers already exist?)
* Instead, bit 10 (1024) of ED is now used to change the default
clipboard to the primary selection.
The alternative might have been an EJ flag or even a special register containing
the name of the default clipboard register.
* partially reverses 8c6de6cc718debf44f6056a4c34c4fbb13bc5020
|
|
* This command exists in Video TECO.
In Video TECO it also supports reading multiple files with a glob pattern -- we do not support that
as I am not convinced of its usefulness.
* teco_view_load() has been extended, so it can read into dot without
discarding the existing document.
|
|
* It continues to default to 67 (C), which is the system clipboard.
But you can now overwrite it e.g. by adding `^^PU~` to the profile.
* This fixes a minor memory leak:
If you set one of the clipboard registers in the profile (initializing
them as plain registers), the clipboard register had been leaked.
The clipboard registers now replace any existing register,
while at the same time preserving the numeric part.
* All remaining Q-Reg table insertions use a new function
teco_qreg_table_insert_unique() which adds an assertion, so that
we notice any future possible memory leaks.
|
|
* The old behavior of throwing an error was inherited from Video TECO.
* The command is now more similar to TECO-11.
* Since -1 is taken, invalid and incomplete UTF-8 byte sequences
are now reported as -2/-3.
I wasn't really able to provoke -3, though.
|
|
* It turns out that `bool` (_Bool) in bitfields may cause
padding to the next 32-bit word.
This was only observed on MinGW.
I am not entirely sure why, although the C standard does
not guarantee much with regard to bitfield memory layout
and there are 64-bit available due to passing anyway.
Actually, they could also be layed out in a different order.
* I am now consistently using guint instead of `bool` in bitfields
to prevent any potential surprises.
* The way that guint was aliased with bitfield structs
for undoing teco_machine_main_t and teco_machine_qregspec_t flags
was therefore insecure.
It was not guaranteed that the __flags field really "captures"
all of the bit field.
Even with `guint v : 1` fields, this was not guaranteed.
We would have required a static assertion for robustness.
Alternatively, we could have declared a `gsize __flags` variable
as well. This __should__ be safe since gsize should always be
pointer sized and correspond to the platform's alignment.
However, it's also not 100% guaranteed.
Using classic ANSI C enums with bit operations to encode multiple
fields and flags into a single integer also doesn't look very
attractive.
* Instead, we now define scalar types with their own teco_undo_push()
shortcuts for the bitfield structs.
This is in one way simpler and much more robust, but on the other
hand complicates access to the flag variables.
* It's a good question whether a `struct __attribute__((packed))` bitfield
with guint fields would be a reliable replacement for flag enums, that
are communicated with the "outside" (TECO) world.
I am not going to risk it until GCC gives any guarantees, though.
For the time being, bitfields are only used internally where
the concrete memory layout (bit positions) is not crucial.
* This fixes the test suite and therefore probably CI and nightly
builds on Windows.
* Test case: Rub out `@I//` or `@Xq` until before the `@`.
The parser doesn't know that `@` is still set and allows
all sorts of commands where `@` should be forbidden.
* It's unknown how long this has been broken on Windows - quite
possibly since v2.0.
|
|
* This was a regression introduced by 257a0bf128e109442dce91c4aaa1d97fed17ad1a.
* The undo token that frees newly allocated teco_machine_qregspec_t must actually
reset the pointer as well since any subsequent token, pushed by teco_undo_qregspec_own(),
will expect a valid pointer.
* Could have been done via
ctx->expectqreg = NULL;
teco_undo_qregspec_own(ctx->expectqreg);
but using a special clear function requires less memory and is easier to understand.
* Added test case. This wouldn't always crash, but should definitely show up in Valgrind.
|
|
* Objects, that are restored with TECO_DEFINE_UNDO_OBJECT_OWN(),
could actually leak memory on rubout since the old object was not
deleted when overwriting it.
* Now that it is, it is crucial to at least nullify objects/pointers
after calling the corresponding push-function.
These conditions are now explicitly documented.
* The test suite now runs successfully under Valgrind even with full leak checking.
|
|
* Curses allows scrolling with the scroll wheel at least
if mouse support is enabled via ED flags.
Gtk always supported that.
* Allow clicking on popup entries to fully autocomplete them.
Since this behavior - just like auto completions - is parser state-dependant,
I introduced a new state method (insert_completion_cb).
All the implementations are currently in cmdline.c since there is some overlap
with the process_edit_cmd_cb implementations.
* Fixed pressing undefined function keys while showing the popup.
The popup area is no longer redrawn/replaced with the Scintilla view.
Instead, continue to show the popup.
|
|
|
|
* Apparently g_utf8_get_char_validated() sometimes(!) returns -2 for null-characters,
so it was considered an invalid byte sequence.
* What's strange and unexplainable is that other uses of the function, as are behind nA and nQq,
did not cause problems and returned 0 for null-bytes.
* This also fixes syntax higlighting of .teco_session files which use the null-byte as the
string terminator.
(.teco_session files are not highlighted automatically, though.)
|
|
characters)
* The teco_qreg_vtable_t::get_string() method should support returning the
length optionally (may be NULL).
This already worked with teco_doc_get_string(), even though it wasn't documented,
and therefore didn't cause problems with regular Q-Registers.
|
|
* We cannot call it "." since that introduces a local register
and we don't want to add an unnecessary syntactic exception.
* Allows the idiom [: ... ]: to temporarily move around.
Also, you can now write ^E\: without having to store dot in a register first.
* In the future we might add an ^E register as well for byte offsets.
However, there are much fewer useful applications.
* Of course, you can now also write nU: instead of nJ, Q: instead of "." and
n%: instead of "nC.". However it's all not really useful.
|
|
* This would actually causes crashes when trying to format numbers.
* The ^R local register has a custom set_integer() method now,
so that the check is performed also when using nU.^X.
|
|
^R now (refs #17)
* This way the search mode and radix are local to the current macro frame,
unless the macro was invoked with :Mq.
If colon-modified, you can reproduce the same effect by calling
[.^X 0^X ... ].^X
* The radix register is cached in the Q-Reg table as an optimization.
This could be done with the other "special" registers as well, but at the
cost of larger stack frames.
* In order to allow constructs like [.^X typed with upcarets,
the Q-Register specification syntax has been extended:
^c is the corresponding control code instead of the register "^".
|
|
* This was a regression introduced in 41ab5cf0289dab60ac1ddc97cf9680ee2468ea6c,
which changed the semantics of teco_doc_undo_set_string().
* Removed undo_append_string() Q-Reg virtual method.
append_string() now does its own undo token emission, so that we can
defer the teco_doc_undo_edit() after the point that the document
was initialized. This is important, so that we can configure the
default encoding on new registers.
|
|
* The previous check could result in false positives if you are editing
a local Q-Register, that will be destroyed at the end of the current macro frame,
and call another non-colon modified macro.
* It must instead be invalid to keep the register edited only if it belongs to the
local Q-Registers that are about to be freed.
In other words, the table that the currently edited Q-Register belongs to, must be
the one we're about to destroy.
* This fixes the solarized.toggle (F5) macro when using the Solarized color scheme.
|
|
This reverts commit 024d26ac0cd869826801889f1299df34676fdf57.
This was re-introducing Clang warnings since gboolean is signed.
I should have read the git blame before re-introducing gboolean...
|
|
|
|
* @EQ$/.../ sets the current directory from the contents of the given file.
@E%$/.../ stores the currend directory in the given file.
* @EQ*/.../ will fail, just like ^U*...$.
@E%*/.../ stores the current buffer's name in the given file.
* It's especially useful with the clipboard registers.
There could still be a minor bug in @E%~/.../ with regard to EOL normalization
as teco_view_save() will use the EOL style of the current document, which
may not be the style of the Q-Reg contents.
Conversions can generally be avoided for these particular commands.
But without teco_view_save() we'd have to care about save point creation.
|
|
* This was unsafe and could easily result in crashes, since teco_qreg_current
would afterwards point to an already freed Q-Register.
* Since automatically editing another register or buffer is not easy to do right,
we throw an error instead.
|
|
The following rules apply:
* All SciTECO macros __must__ be in valid UTF-8, regardless of the
the register's configured encoding.
This is checked against before execution, so we can use glib's non-validating
UTF-8 API afterwards.
* Things will inevitably get slower as we have to validate all macros first
and convert to gunichar for each and every character passed into the parser.
As an optimization, it may make sense to have our own inlineable version of
g_utf8_get_char() (TODO).
Also, Unicode glyphs in syntactically significant positions may be case-folded -
just like ASCII chars were. This is is of course slower than case folding
ASCII. The impact of this should be measured and perhaps we should restrict
case folding to a-z via teco_ascii_toupper().
* The language itself does not use any non-ANSI characters, so you don't have to
use UTF-8 characters.
* Wherever the parser expects a single character, it will now accept an arbitrary
Unicode/UTF-8 glyph as well.
In other words, you can call macros like M§ instead of having to write M[§].
You can also get the codepoint of any Unicode character with ^^x.
Pressing an Unicode character in the start state or in Ex and Fx will now
give a sane error message.
* When pressing a key which produces a multi-byte UTF-8 sequence, the character
gets translated back and forth multiple times:
1. It's converted to an UTF-8 string, either buffered or by IME methods (Gtk).
On Curses we could directly get a wide char using wget_wch(), but it's
not currently used, so we don't depend on widechar curses.
2. Parsed into gunichar for passing into the edit command callbacks.
This also validates the codepoint - everything later on can assume valid
codepoints and valid UTF-8 strings.
3. Once the edit command handling decides to insert the key into the command line,
it is serialized back into an UTF-8 string as the command line macro has
to be in UTF-8 (like all other macros).
4. The parser reads back gunichars without validation for passing into
the parser callbacks.
* Flickering in the Curses UI and Pango warnings in Gtk, due to incompletely
inserted and displayed UTF-8 sequences, are now fixed.
|
|
* When enabled with bit 2 in the ED flags (0,4ED),
all registers and buffers will get the raw ANSI encoding (as if 0EE had been
called on them).
You can still manually change the encoding, eg. by calling 65001EE afterwards.
* Also the ANSI mode sets up character representations for all bytes >= 0x80.
This is currently done only depending on the ED flag, not when setting 0EE.
* Since setting 16,4ED for 8-bit clean editing in a macro can be tricky -
the default unnamed buffer will still be at UTF-8 and at least a bunch
of environment registers as well - we added the command line option
`--8bit` (short `-8`) which configures the ED flags very early on.
As another advantage you can mung the profile in 8-bit mode as well
when using SciTECO as a sort of interactive hex editor.
* Disable UTF-8 checks in 8-bit clean mode (sample.teco_ini).
|
|
* ^Uq however always sets an UTF8 register as the source
is supposed to be a SciTECO macro which is always UTF-8.
* :^Uq preserves the register's encoding
* teco_doc_set_string() now also sets the encoding
* instead of trying to restore the encoding in teco_doc_undo_set_string(),
we now swap out the document in a teco_doc_t and pass it to an undo token.
* The get_codepage() Q-Reg method has been removed as the same
can now be done with teco_doc_get_string() and the get_string() method.
|
|
(refs #5)
|
|
or codepoints) (refs #5)
* This is trickier than it sounds because there isn't one single place to consult.
It depends on the context.
If the string argument relates to buffer contents - as in <I>, <S>, <FR> etc. -
the buffer's encoding is consulted.
If it goes into a register (EU), the register's encoding is consulted.
Everything else (O, EN, EC, ES...) expects only Unicode codepoints.
* This is communicated through a new field teco_machine_stringbuilding_t::codepage
which must be set in the states' initial callback.
* Seems overkill just for ^EUq, but it can be used for context-sensitive
processing of all the other string building constructs as well.
* ^V and ^W cannot be supported for Unicode characters for the time being without an Unicode-aware parser
|
|
teco_state_start_get() (refs #5)
|
|
There is a widespread myth that they could take up to 6 bytes.
|
|
* this required adding several Q-Register vtable methods
* it should still be investigated whether the repeated calling of
SCI_ALLOCATELINECHARACTERINDEX causes any overhead.
|
|
unsigned integer
* SCI_GETCHARAT is internally casted to `char`, which may be signed.
Characters > 127 therefore become negative and stay so when casted to sptr_t.
We therefore cast it back to guchar (unsigned char).
* The same is true whenever returning a string's character to SciTECO (teco_int_t)
as our string type is `gchar *`.
* <^^x> now also works for those characters.
Eventually, the parser will probably become UTF8-aware and this will
have to be done differently.
|
|
* gboolean cannot be used since it is a signed type
* bool is still more readable, even though we mostly use glib typedefs.
* AFAIK the glib types are deprecated, so sooner or later we will switch
to stdint/stdbool types anyway.
|
|
|
|
(-Wsingle-bit-bitfield-constant-conversion)
* gboolean is defined as gint which is a signed type.
A gboolean 1-bit-wide bitfield cannot have the values 0 and 1 but only 0 and -1.
* This wasn't practically a bug unless you would try to compare one of those bitfields
with TRUE.
* All of those bitfields are now guint, even though this is less self-documenting.
|
|
* This was setting only the teco_doc but wasn't calling the necessary
set_string() methods.
* The idiom [$ FG...$ ]$ to change the working directory temporarily
now works.
* Similarily you can now write [~ ^U~...$ ]~ to change the clipboard
temporarily.
* Added test suite cases. The clipboard is not tested since
it's not supported everywhere and would interfer with the host system.
* Resolved lots of redundancies in qreg.c.
The clipboard and workingdir Q-Regs have lots in common.
This is now abstracted in the "external" Q-Reg base "class"
(ie. via initializer TECO_INIT_QREG_EXTERNAL()).
It uses vtable calls which is slightly more inefficient than per
register implementations, but avoiding redundancies is probably more
important.
|
|
|
|
registers
* An empty but valid teco_string_t can contain NULL pointers.
More precisely, a state's done_cb() can be invoked with such empty strings
in case of empty string arguments.
Also a registers get_string() can return the NULL pointer
for existing registers with uninitialized string parts.
* In all of these cases, the language should treat "uninitialized" strings
exactly like empty strings.
* Not doing so, resulted in a number of vulnerabilities.
* EN$$ crashed if "_" was uninitialized
* The ^E@q and ^ENq string building constructs would crash for existing but
uninitialized registers q.
* ?$ would crash
* ESSETILEXER$$ would crash
* This is now fixed.
Test cases have been added.
* I cannot guarantee that I have found all such cases.
Generally, it might be wise to change our definitions and make sure that
every teco_string_t must have an associated heap object to be valid.
All functions returning pointer+length pairs should consequently also never
return NULL pointers.
|
|
begin with an equals character
* Has been observed on Windows Server 2008 with Glib 2.74.1-1, but not on the
Github CI runner.
|
|
g_listenv()
* This is assumed to fix current Windows CI build problems caused by g_getenv() returning NULL
for keys contained in g_listenv(), which is probably a new Glib bug.
* Using g_get_environ() is more efficient since we do not have to repeatedly search
through the environment array with g_getenv().
* Windows 2000 - which supposedly relied on the old code because of its own bugs - is
no longer supported by our minimum Glib version anyway.
|
|
|
|
* Test case: sciteco -e '[a'
[aEX$$ in interactive mode would also crash.
* No longer use a destructor - it was executed after the Q-Reg view was
destroyed.
* Instead, we now explicitly call teco_qreg_stack_clear() in main().
* Added a regression test case.
|
|
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.
|