Commit graph

9049 commits

Author SHA1 Message Date
Daniel Kochmański
c33c8f2ef7 tests: add a test for failed conversion byte->char
Sometimes bytes are outside of the character range. In that case we should
signal an error when we try to read them.
2025-08-11 10:01:41 +02:00
Daniel Kochmański
41f52d8d0f streams: bivalent stream signals a condition for bytes out of range
Sometimes a byte may be not within the character code range. In that case, when
we read the char, the system will signal a condition.

Alternatively (and that's the behavior before this commit) we could return the
character #\Nul. That was done by virtue of ECL_CHAR_CODE skipping tag bytes, so
the returned NIL was treated as 0.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
43fef5fad8 streams: address a possible segfault in sequence streams
Byte streams transcoding to :ucs-2 and :ucs-4 don't call ecl_set_stream_elt_type
effectively not initializing .byte_buffer.  Moreover functions seq_in_read_byte8
and seq_out_write_byte8 assume the vector type to be an octet based, and they
increment the stream position and test for its limit according to that.

That means that ecl_binary_read_byte and ecl_binary_write_byte calls would
segfault when seq_in_read_byte8 and seq_out_write_byte8 are called.

Both conditions could be easily mitigated by initializing .byte_buffer manually
and fixing seq_*_*_byte8 functions to account for the byte size, but there is no
need for that, because for these streams we are not using

ecl_binary_*_byte
ecl_eformat_*_byte

so byte8 functions are not called and .byte_buffer is not used.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
c7d78a412e tests: add tests for bivalent streams based on sequences 2025-08-11 10:01:40 +02:00
Daniel Kochmański
26a22057e5 streams: introduce direct bivalent sequence streams
Previously sequence streams always needed to go through the eformat and binary
encoders and decoders -- if bytes were too big, then we couldn't create sequence
streams from them.

After this commit it is possible to pass a character stream or a byte stream and
use it as a bivalent stream without a roundtrip for encoding and decoding.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
688eceb9ed streams: bring bivalent streams UNREAD-CHAR and UNREAD-BYTE together
This finishes the commit that adds unread-byte and peek-byte functions to the
mix in that for bivalent stream UNREAD-BYTE will work for the subsequent
READ-CHAR and vice versa. This also caters to transcoding etc.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
b7eaf35502 streams: move byte_stack to strm_os and improve UNREAD-BYTE
The .byte_stack is used only by files to:
a) unread a single octet when we use fallback LISTEN implementation
b) unread bytes that make a character when UNREAD-CHAR is used

The latter is important to transcode characters from one external format to
another (i.e see the test external-format.0003-transcode-read-char).

This commit improves the function unread-byte to do the same brinding bivalent
streams almost to parity with regard to that implementation (see next commit).

That makes the implementation of eformat cleaner, .byte_stack more
self-contained, and saves us consing new byte stack for sequence streams (where
it was simply ignored, not to mention not entirely correct - because we've used
a .byte_stack length to decrement the pointer position while the byte could have
more bits than one octet).

Other optimizations that could be done here:
- make the byte stack an adjustable vector to avoid consing on each unread
2025-08-11 10:01:40 +02:00
Daniel Kochmański
10a1e8dddf streams: invert .last_char processing and UNREAD-CHAR
Previously we've stored in this field the last read char, while now we store
there the last unread char. This way we can't tell whether the last read char
was the same as the unread one, but on the other hand this way requires less
bookeeping and the code shape is similar to UNREAD-BYTE.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
a726cdf879 streams: get rid of last_code slot in the structure
It was used to store bytes for unread, but we are going to change how unread
works, and we still can simply test for newline and encode behavior directly in
unread-char for newlines.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
c8f41912a0 streams: echo-stream treats last_byte as a flag
Instead of remembering the last unread object and its type, it simply yots down
the fact that something has been unread (and clears on read), and delegates the
question to the input stream.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
31a3fc904e streams: move ecl_generic_unread_byte to ecl_binary_unread_byte 2025-08-11 10:01:40 +02:00
Daniel Kochmański
ca845457f8 streams: switch to the new binary reader/writer implementation
We drop warying generic-read/write variants in favor of using binary encoders
introduced in earlier commits.

This will allow for unified handling of unread bytes and characters and
transcoding both in bivalent streams.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
1136d55122 streams: introduce a notion of a byte buffer in a stream
The byte buffer is used for encoding and decoding both characters and bytes.
Previously we've used a stack-allocated array, but this doesn't cut it when it
comes to binary streams, where the byte may be a "finite recognizable subtype of
integer" (c.f specification of OPEN), because then the array may have more
elements.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
ba422ec9dd streams: add binary encoders and decoders to the mix
This will allow us to transcode characters to bytes and vice versa. This is
necessary to implement conductive UNREAD-BYTE and UNREAD-BYTE, but will allow us
to also add low-level parsers for binary objects in the future.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
5fe96b8339 tests: add sequence stream tests for new functionality
- ensure that all byte element types are handled by binary sequence streams
- ensure that the vector fill pointer is followed by the input sequence
2025-08-11 10:01:40 +02:00
Daniel Kochmański
c7f534771a streams: sequence input stream follows the vector length
This is to allow working with sequence streams where the vector may change after
the stream has been created.

When the user specifies :END to be some fixed value, then we upkeep that
promise, but when :END is NIL, then we always consult the vector fillp.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
086f0a4bef streams: allow for sequence streams to handle all byte arrays
Previously when we couldn't convert the vector element type to a character,
creating sequence streams failed even when we were expecting the binary stream.
From now on it is possible to vectors with upgraded types being any integer.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
ea11e2c433 streams: rename common sequence stream accessors
SEQ_{INPUT,OUTPUT}* -> SEQ_STREAM*

Don't use IO_STREAM_ELT_TYPE in sequences and define SEQ_STREAM_ELT_TYPE
instread to avoid ambiguity.

This is a cleanup that signifies similarities between both objects.
2025-08-11 10:01:40 +02:00
Daniel Kochmański
37c3955180 manual: add documentation for new binary stream interfaces 2025-08-11 10:01:38 +02:00
Daniel Kochmański
7ee0977a50 tests: add test for binary and bivalent streams with extensions
Tests reading, peeking and unreading both characters and bytes.
2025-08-11 10:01:37 +02:00
Daniel Kochmański
a8e57c60a5 streams: implement new interfaces for unreading and peeking bytes
ecl_file_ops has two new members:

  void (*unread_byte)(cl_object strm, cl_object byte);
  cl_object (*peek_byte)(cl_object strm);

C API additions:

  void ecl_unread_byte (cl_object byte, cl_object strm)
  cl_object ecl_peek_byte (cl_object strm)

  si_unread_byte(cl_object strm, cl_object byte)    [1]
  si_peek_byte(cl_object strm, cl_object byte)      [2]

Lisp API additions:

  (ext:unread-byte stream byte) :: integer          [1]
  (ext:peek-byte   stream byte) :: (or integer nil) [2]

  (gray:stream-unread-byte stream byte) :: null
  (gray:stream-peek-byte stream) :: (or integer :eof)

We implement a "generic" version of unread-byte by storing it in a new slot
last_byte.
2025-08-11 10:01:37 +02:00
Daniel Kochmański
a887d040a2 tests: add a new test suite "stream"
Currently it contains only a check for a recently fixed bug in:
streams: fix a braino in str_in_unread_char
2025-08-11 10:01:37 +02:00
Daniel Kochmański
a916a5ccff tests: make finishes return the values from the executed form 2025-08-11 10:01:37 +02:00
Daniel Kochmański
e98e36dfca streams: fix a braino in str_in_unread_char
We've tested a wrong variable so this function allowed us to plum into negative
indexes.
2025-08-11 10:01:37 +02:00
Daniel Kochmański
407fe456fe streams: make ecl_read_byte return OBJNULL on EOF
This is to allow for sequence streams to return arbitrary objects (when
appropriately constructed) without many changes.
2025-08-11 10:01:37 +02:00
Daniel Kochmański
431132e4d1 streams: ecl_file_ops cleanup and some minor fixes
1. ecl_peek_char had outdated comment presumbly from before we've introduced
   stream dispatch tables - that comment has been removed.

2. fix erroneous specializations

   - of STREAM-UNREAD-CHAR

   By mistake we had two methods specialized to ANSI-STREAM, while one were
   clearly meant to specialize to T (in order to call BUG-OR-ERROR).

   - of winsock winsock_stream_output_ops

     stream peek char was set to ecl_generic_peek_char instead of
     ecl_not_input_read_char

3. change struct ecl_file_ops definition

a) ecl_file_ops structure change order of some operations to always feature READ
   before WRITE (for consistency)

b) we are more precise in dispatch function declaration and specify the return
   type to be ecl_character where applicable
2025-08-11 10:01:37 +02:00
Daniel Kochmański
fad7073f10 ffi: convert-to-foreign-string: ensure a cstring
The function operates on base_string while if it was supplied with an extended
string then ecl_base_char array became ecl_character, and that lead to bad
copies. To fix it we ensure that the passes string is first coerced to cstring.
2025-08-11 09:16:00 +02:00
Daniel Kochmański
77ceb401f9 doc: man: stack sizes are specified in bytes not kilobytes
Fixes #788.
2025-08-10 22:29:16 +02:00
Daniel Kochmański
bebb43d558 INSTALL: update the version of te tested emsdk version to 4.0.12
That's the current latest and it works OK when we compile host and wasm target
according to the most up-to-date instructions.
2025-08-04 10:06:31 +02:00
Marius Gerbershagen
a7126313d9 Merge branch 'refactor-streams' into 'develop'
Split file.d into various stream implementations

See merge request embeddable-common-lisp/ecl!351
2025-07-29 14:35:55 +00:00
Daniel Kochmański
3f2ad992e6 Merge branch 'openbsd-file_cnt' into 'develop'
openbsd: implement FILE_CNT() on opaque FILE

See merge request embeddable-common-lisp/ecl!354
2025-07-29 11:23:21 +00:00
Daniel Kochmański
68a78e252f msvc: update makefile 2025-07-26 16:59:42 +02:00
Daniel Kochmański
6ce9c22dda stream: split file.d into different stream types
This commit splits one garguntulum file into numerous orthogonal stream types:

- strm_os -- c99/posix/windows streams
- strm_clos -- gray streams
- strm_string -- string streams
- strm_composite -- composite streams (echo, broadcast, synonym ...)
- strm_common -- common errors, byte manipulation routines etc
- strm_sequence -- si_write_sequence and si_read_sequence (fast I/O)
- strm_eformat -- external format processing routines (unicode etc)

After this split file.d contains only open/close. This will be the place to
dispatch to a virtual filesystem.
2025-07-26 16:59:42 +02:00
Daniel Kochmański
6fcb977052 stream: factor out general stream interface from file.d 2025-07-26 16:59:42 +02:00
Daniel Kochmański
4542318b80 stream: add missing lisp interfaces
The api for these is cleaned up compared to Common Lisp counterparts.
2025-07-26 16:59:42 +02:00
Daniel Kochmański
a5c922b849 stream: unread_error and unread_twice are now not continuable
At least in two from four cases continuing from the error lead to an error:

- for concatenated stream we've tried to dispatch on CAR that was NIL (segfault)
- for string stream we've decremented the position below 0

Also change these functions to defined macros ecl_unread_* that expand to
FEerror (in internal.h). This is in anticipation of splitting file.d.
2025-07-26 16:59:42 +02:00
Daniel Kochmański
b8e8899280 stream: change order of arguments in internal write_byte methods
That said this is inconsistent with how we implement ECL-WRITE-CHAR, and with
STREAM-WRITE-BYTE, so for convenience we swap the argument order.
2025-07-26 16:59:42 +02:00
Daniel Kochmański
c828e7b64d core: move atomics from threads directory to core
Atomics are needed by stacks.

Replace ecl_atomic_push -> ecl_atomic_psh that takes as an argument a
preallocated cons. ecl_atomic_push is replaced with a macro.
2025-07-26 16:59:42 +02:00
Daniel Kochmański
0dad009527 c/makefile: group files in rough categories 2025-07-26 16:59:42 +02:00
Daniel Kochmański
ca8eea81a1 Update gitlab-ci to run pipeline less frequently (2) 2025-07-26 16:59:24 +02:00
Daniel Kochmański
31a82c296c Update gitlab-ci to run pipeline less frequently
We've hit qutie fast 3/4 of the limit, so this pull request limits pipelines to
be run only when we commit to the branch develop and on merge requests.
2025-07-26 08:31:28 +02:00
Sebastien Marie
b427defc39 openbsd: implement FILE_CNT() on opaque FILE
On OpenBSD, FILE is opaque (starting from upcoming OpenBSD 7.8).
FILE_CNT() macro is implementable using `size_t __freadahead(FILE *stream)` function (provided for gnulib compat).
2025-07-23 08:51:20 +00:00
Daniel Kochmański
84e9b0b450 Merge branch 'cross-compilation-core' into 'develop'
Cross compilation improvements

Closes #741 and #747

See merge request embeddable-common-lisp/ecl!352
2025-07-21 08:04:44 +00:00
Daniel Kochmański
3e3da7dc27 gitlab-ci.yml: specify artifacts and make test jobs work
We don't fail when some tests don't pass -- we run them instead and the
submitter/reviewer now can check results before merging.
2025-07-21 10:02:08 +02:00
Marius Gerbershagen
b77a0bbf06 update compilation instructions for iOS and emscripten
We don't need a separate host compiler anymore.
2025-07-19 16:33:22 +02:00
Marius Gerbershagen
f0ef267ce7 update compilation instructions for android
With recent versions of the android NDK, there is no need to create a
separate toolchain anymore. Moreover, the LDFLAGS and CPPFLAGS are
obsolete. Also, we can't call the C compiler with a `-Dandroid`
argument as we used to since that conflicts with uses of the `android`
identifier within the header files of the android C standard library.
Therefore, we change from `thehost=android` to `thehost=ANDROID` in
uppercase. Finally, make the test script run more reliably by starting
an adb server before we change TMPDIR.
2025-07-19 16:33:22 +02:00
Marius Gerbershagen
6a3605b768 clos: builtin classes have the same index independent of configure options
This is needed to allow for cross compiling from a compiler with a
different set of configure options (e.g. compiling for a target which
doesn't support complex floats from a host which does).
2025-07-19 16:33:22 +02:00
Marius Gerbershagen
b194811ee3 src/util: add script to help in testing cross compilation 2025-07-19 16:33:22 +02:00
Marius Gerbershagen
d51ce511f6 handle *features* entirely in the configure script
Previously, there were a lot of places that turned on or off C macros
which finally determined whether some particular entry was found
in *features* or not. Now, we do this all in the configure script.
This is necessary for cross compilation from a non-compatible host
which may have different features.
2025-07-19 16:33:22 +02:00
Marius Gerbershagen
cd90ecfd55 cmp: signal internal error in wt-vv-value if we detect a programming error 2025-07-19 16:33:22 +02:00