Menu

SVN-Code Commit Log


Commit Date  
[r13102] by mikeaubury

ChangeLog: fill in 1.6.3, and summarise the changes since it

1.6.3 had no entries at all. Added, from the revisions between the 1.6.2 and
1.6.3 releases: web UI work, CLOSE CURSOR as a synonym for CLOSE, CONFIG = on a
form field accepting a JSON object, fgl_messagebox, the move to ExtJS 7.

The 1.8.1 section covers 162 revisions, so it is grouped by period rather than
listing each one - many of the individual messages are "." or "New build" and a
flat list would not be readable. Four groups: the JSON and web UI work through
late 2025, the build system rewrite in spring 2026, the Angular UI and
clean-checkout build fixes in August, and this month's compiler and C# back end
work.

2026-09-07 15:12:11 Tree
[r13101] by mikeaubury

Fix mk_states_opt.c so it builds with gcc 14

Three pieces of pre-C99 style that newer compilers no longer accept, reported
by a user building with gcc 14:

main() { -> int main (void)
int get_nints(...) -> static int get_nints(...)
printf("arr_%d,\n",a,a) -> printf("arr_%d,\n",a)

Implicit int was removed from the language in C99 and gcc 14 rejects it
outright rather than warning, which is what stopped the build:

error: return type defaults to 'int' [-Wimplicit-int]

get_nints is used only in this file, so static both silences the
missing-prototype warning and says what is true. The printf had two arguments
for one conversion.

This program generates the parser state table, so the old and new versions were
built side by side and their output compared: byte for byte identical, 1167625
bytes. The change only makes the generator compile; what it generates is
unchanged.

2026-09-07 15:11:55 Tree
[r13100] by mikeaubury

C# back end: reject a GOTO that jumps into a block

C# allows a goto to leave blocks but not to enter one: the label has to be in
the same block as the goto, or in one enclosing it. 4GL puts no such limit on
it and neither does C, so a program can be perfectly good 4GL and have no valid
C# translation. That used to surface as

error CS0159: No such label 'x' within the scope of the goto statement

against generated code, which takes some tracing before it is clear that the
4GL is what needs changing. It is now reported where it happens:

| Error at line 529, character 19
| GOTO carryon jumps into a block - the label is not in this branch, nor in
| one containing it. C# does not allow that, so this needs restructuring
| (move the label out, or use a flag and test it after the branch)

Every command list is a block: entering one pushes a fresh id and leaving pops
it, so the stack is the path from the function body to the current point. A
label's path is recorded where it is declared and a goto's likewise, and the
jump is legal exactly when the label's path is a prefix of the goto's.

The prefix test is the point. Comparing nesting depth is not enough: in the
case that prompted this the goto sits deeper than its label and still cannot
reach it, because the two are in the IF and the ELSE of the same statement -
siblings, not ancestor and descendant.

A goto to a label that is declared nowhere is left alone. That is a different
fault and not one this check should be guessing about.

Checked against 160 programs: no program that compiled before fails now, and
besides the case that prompted it the check found one more genuine instance.

2026-09-07 10:33:05 Tree
[r13099] by mikeaubury

C# back end: a switch needs its labels to be the subject's type

4GL will test an INTEGER against "1", converting as it goes. C# requires the
case labels to have the same type as the switch expression, so such a CASE was
emitted as a switch that would not compile.

Where the subject and its labels disagree about being character data, the
if/else fallback is used instead - it compares through the same conversion the
rest of the generated code uses, so the meaning is unchanged.

2026-09-06 13:53:00 Tree
[r13098] by mikeaubury

C# back end: restore three fixes lost to a revert

These were committed in r13095 and then reverted out of the working copy while
undoing an unrelated bad edit to the same file. The commit stands; the working
copy did not, and later work was built without them. Restored and verified
against the programs that first showed each:

- a struct with a field initialiser needs an explicit parameterless
constructor, and an array member is emitted with an initialiser
- two WHEN clauses may test the same value; 4GL runs the first that matches
and a C# switch rejects duplicate labels, so those take the if/else
fallback that already existed
- the keyword escape must not survive into a flattened identifier -
"InVar_a_@..." does not parse, and the flattened name cannot be a keyword

The lesson is narrower than it looks: revert takes the whole file, so undoing
one edit to a file that carries several loses the rest.

2026-09-06 13:47:01 Tree
[r13097] by mikeaubury

C# back end: type a function from its widest RETURN

A function not covered by the prototypes has its signature worked out by
scanning its RETURN statements - and the scan stopped at the first one it
found. A 4GL function may return different numbers of values on different
paths, so where a later path returned more, the function was typed too narrow
and its calls would not compile.

It now keeps the RETURN that yields the most values, matching how the compiler
chooses between a function's prototype variants (r13096): the signature has to
suit every call site, and the widest does.

2026-09-06 13:16:19 Tree
[r13096] by mikeaubury

Choose deliberately between a function's return shapes

A 4GL function may return different things on different paths - a value on one
and nothing on another, or a SMALLINT here and a DECIMAL there. fglproto emits
one prototype per shape, and is_bolton_function answered with whichever came
first, so which shape a back end saw depended on the order they happened to be
written. Arbitrary, and for a back end with a strict type system it decides
whether the program compiles at all.

The widest now wins: a function returning SMALLINT on one path and DECIMAL on
another is a DECIMAL function, and the narrow value converts to it without
loss. Where two shapes return different numbers of values the one returning
more wins, so no call site loses a result.

Ordering is SMALLINT < INTEGER < INT8 < DECIMAL < FLOAT < CHAR, comparing at
the first position where two shapes differ.

No change to the C back end's output on the example suite - it accepts either
shape, so it never depended on the choice.

2026-09-06 13:08:55 Tree
[r13095] by mikeaubury

C# back end: make ORDER BY reports compile

The ordered report path was almost complete - it creates the temp table,
prepares the insert, re-reads with an ORDER BY and replays the rows, matching
what A4GL_make_report_table and its siblings do in the C runtime, down to the
c0, c1 column naming. Three naming faults stopped any of it compiling:

- the reread cursor was used and never declared. Ordinary cursors become
class members when their DECLARE is compiled; this one is invented for the
reread and has no DECLARE, so it needs a local.
- the prepared statement was referenced without the Statement_ prefix that
print_prepare_cmd gives it.
- both, and a statement-level CALL ... RETURNING, need the module prefix
inside a report, which is emitted as a nested class. The expression form of
a call already had it; the statement form did not.

A4GL_cs_module_prefix exports that prefix for compile_cs_sql.c, which generates
the report body and cannot see the static function in compile_cs.c.

A report with an ORDER BY now compiles. Whether its rows come back sorted has
not been shown - that needs a database behind it.

2026-09-06 13:03:59 Tree
[r13094] by mikeaubury

C# runtime: date arithmetic, blob fetch, and two missing entry points

DateAdd and DateDiff. A DATE is a day count in 4GL - day 0 is 31 December 1899
- so adding a whole number adds days. C# has no operator for DateOnly against
an int and none can be added to a type we do not own, so the generator calls
these instead of writing the arithmetic inline.

GetData(out byte[]?, int) for BYTE and TEXT columns. The generator used to pass
the target by value, which could assign nothing. A driver may hand back either
bytes or a string, so a string is encoded rather than rejected - which is what
a program reading a TEXT column into a BYTE variable expects.

UI.ClearWindow: the protocol message existed and the entry point did not.

A report's COLUMN takes whatever the 4GL gave it, commonly a SMALLINT, rather
than requiring an int.

2026-09-05 22:00:36 Tree
[r13093] by mikeaubury

C# back end: report generation fixes

A report is emitted as a nested class, so the module's own members are not in
scope by their bare names. The body refers to SQL and to the error hook exactly
as module code does, and there are sixty emission sites - too many to qualify
individually - so the report now forwards both to the module once. A nested
class may reach its enclosing type's protected members, which is what makes
that legal.

startReportOrdered and finishReportReordered were called by the ORDER BY path
and defined nowhere at all, so no report with an ORDER BY could be compiled.
They are defined here. The ordering itself is still not done - print_report_
table's "make the table" phase emits nothing, so there is no temp table to
collect rows into and re-read - and rather than quietly produce a report in the
wrong order, the start says so once and then runs unordered. The rows are
right; only their order is not.

outputMode was assigned unqualified in one place when it is a field on the
report driver.

"while (1)" is not a condition in C#.

Note: r13092 carried more than its message describes. Besides the RUN ...
RETURNING fix it also contains DATE increment and decrement (the "d++"
shortcut has no meaning for a day count), DATE arithmetic through the runtime,
BYTE and TEXT columns fetched by out rather than by value, the module prefix on
seventeen cursor and statement references inside reports, and identifier
escaping in record initialisation - a fourth site where a field named after a
C# keyword was emitted bare. The log could not be corrected after the fact:
this repository has no pre-revprop-change hook.

2026-09-05 21:59:56 Tree
Older >