Menu

SVN-Code Commit Log


Commit Date  
[r13108] by mikeaubury

configure: substitute SQLUID/SQLPWD again, and the other aubitrc placeholders

etc/aubitrc.in carries @SQLUID@ and @SQLPWD@ for A4GL_SQLUID and
A4GL_SQLPWD, the login used for DATABASE and DEFINE LIKE at compile
time and for the procedural DATABASE statement at run time. The old
configure.in had --with-sqluid/--with-sqlpwd and AC_SUBST for both.
The rewritten configure.ac had neither, so the placeholders reached
the installed aubitrc verbatim.

The runtime then read them as credentials and presented them to the
server, so every connection failed with

-951 Incorrect password or user @SQLUID@ is not known on the
database server.

A machine set up before the rewrite keeps working, because the
personal ~/.aubit4gl/aubitrc written by the older configure sets both
to empty and is read last, masking the broken value. Only a fresh
install, or a user whose personal rc lacks those lines, sees the
failure - which is why this did not show up locally.

Restores both options, defaulting to empty. Empty is the right
default: it means "connect as the current user", and matches what the
previous build produced when neither option was given.

Four other placeholders were leaking the same way and are now
substituted too, aubitdir_src to the source root and the rest to
empty. An unsubstituted @NAME@ is never a usable value - it reaches
the runtime as that literal string. Only @PG_COPTS@ remains, on a line
that is already commented out and marked as not set.

configure regenerated with autoreconf.

2026-09-10 18:33:26 Tree
[r13107] by mikeaubury

esqlc: INT8 host variables on older CSDK, and safer error message handling

Four fixes in the Informix driver.

1. Build failure on a CSDK that does not know BIGINT.

Three host variables were declared "bigint", a type that only exists
in a CSDK new enough to know BIGINT; older ones fail to compile with
"unknown type name 'bigint'". Two other uses in this same file were
already guarded by CBIGINTTYPE - that guard had simply never been
applied to these three.

They are now guarded the same way, falling back to "int8", which
esqlc rewrites to ifx_int8_t before the C compiler sees the token.
That is the 12 byte struct rather than a scalar, so the fallback
converts with ifx_int8cvasc/ifx_int8toasc - a decimal string being
the only conversion that keeps all 64 bits - and binds as INT8,
since a CSDK without CBIGINTTYPE has no BIGINT to bind to either.

The two branches deliberately use different variable names. esqlc
does not evaluate the #if; it records every declaration it walks
past, so a shared name leaves the last one winning and the bigint
branch gets marshalled as ifx_int8_t. That still compiles, and
silently reads 12 bytes out of an 8 byte variable.

2. Error text reaching the caller with its parameter unsubstituted.

get_sqlerrm() relied on GET DIAGNOSTICS to fill in the message
parameter. Not every CSDK does, so a caller could be shown
"user %s is not known" instead of being told which user was
rejected.

3. Message templates used as printf format strings.

get_errmsg() handed the template from rgetmsg() to sprintf with a
single argument. Informix has templates carrying up to four
conversions, so the remaining ones were read off the stack.

Both now go through one helper that substitutes sqlca.sqlerrm
textually and drops any conversions left over, so text supplied by
the server is never used as a format.

4. An unset SQLPWD became an empty password.

acl_getenv() returns an empty string for a variable that is not set,
never a null pointer, so initPassword() has to use the
_not_set_as_0 form the way initUser() already does. With the plain
form a user name with no password was presented as USER x USING '',
which the server refuses with -951 - indistinguishable from a wrong
password. That case now falls back to a connection as the current
user, and warns that the configured name could not be used.

Also adds debug to the connect path: the database, the user name and
where it came from, and on failure the sqlcode and sqlerrm, which is
where the name the server actually saw appears. The password itself is
never logged.

2026-09-10 18:33:08 Tree
[r13106] by mikeaubury

4glc: emit INT8 rather than the token name for BIGINT/INT8 columns

The Informix sqlpack rendered an INTEGER8 column type as the literal
string "INTEGER8" - the internal token name, not a SQL type. Every
neighbouring rule emits the real spelling (SERIAL8 gives "SERIAL8"),
so this one was the odd one out.

The server rejected the resulting DDL with -9628 "Type (integer8) not
found", which made BIGINT and INT8 unusable in CREATE TABLE and in any
other statement naming the type, a cast included.

Now emits INT8: accepted by every Informix version where the type
exists (BIGINT needs 11.x), and matching the DTYPE_INT8 the runtime
already uses for these columns. Also records the DDL_INT8 feature
marker, as the surrounding types do.

2026-09-10 18:32:46 Tree
[r13105] by mikeaubury

Give generated code the POSIX header as well as the C ones

A CODE block is C written by hand inside a 4GL program, and it reaches for
usleep as readily as for the standard functions the header chain already
provides. Without unistd.h those were implicitly declared, which was legal C89
and is an error in gcc 14 - so a program with such a block stopped compiling.

Not guarded on HAVE_UNISTD_H: the generated-code header chain does not pull in
a4gl_incl_config.h, so no HAVE_* symbol is defined by the time this is read.
Every platform this builds for - Linux, macOS, WSL2, MinGW-w64, FreeBSD -
provides the header, so it is included directly.

2026-09-07 15:31:42 Tree
[r13104] by mikeaubury

ace: pass ints to A4GLSQL_next_column, not 4GL INTEGERs

The CODE block in get_cols passed the addresses of two 4GL INTEGERs to

int A4GLSQL_next_column(char** colname, int* dtype, int* size);

A 4GL INTEGER is a long, so on a 64-bit platform the callee filled four bytes
of each eight-byte variable and left the rest as it found it. That worked only
because both happened to be zero when it ran, and gcc 14 rejects it outright:

error: passing argument 2 of 'A4GLSQL_next_column' from incompatible
pointer type

The values are now taken in ints and copied across, which is what the API
describes.

2026-09-07 15:31:37 Tree
[r13103] by mikeaubury

gzpacked: cast the handle back in the three macros that did not

The header maps the stdio calls onto zlib's, and fopen there hands back a
gzFile cast to FILE *, so every macro has to cast it back before use. Five did.
ftell, fseek and rewind did not:

#define fclose(a) gzclose((gzFile)(a)) <- casts
#define ftell(a) gztell(a) <- did not

Passing a FILE * where a gzFile is expected was a warning until gcc 14, which
rejects it:

error: passing argument 1 of 'gztell' from incompatible pointer type

Only ftell actually broke the build - fseek and rewind are not reached on this
path - but all three carry the same fault, so all three now cast as the rest of
the file already does.

2026-09-07 15:31:19 Tree
[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
Older >