On Dec 2, 2025, at 4:49 PM, M.Hall <[email protected]> wrote:
This was from me complaining to Jurgen in January 2025 that macos
didn't have quad-rval because it doesn't have glibc and initstate_r
-- even though it *does* have 'initstate'. The changes were around
svn 1820.
So your macos finds initstate_r and friends?
On Tue, Dec 2, 2025 at 3:32 PM Paul Rockwell <[email protected]>
wrote:
In src/Quad_RVAL.cc <http://quad_rval.cc/> and the GNU APL info
doc, it's stated that the ⎕RVAL operator requires glibc. This is
stated to be required due to the use of the glibc functions
random_r(), which would also imply the use of initstate_r() and
setstate_r() to initialize and set the state.
However, looking at the source, there is no use of these glibc
functions. The code uses random(), initstate(), and setstate() --
which are available on platforms that use libraries other than
glibc (for example macOS).
//----------------------------------------------------------------------------
Quad_RVAL::Quad_RVAL()
: QuadFunction(TOK_Quad_RVAL)
{
*enum*{ count = *sizeof*(subfunction_infos) /
*sizeof*(*subfunction_infos) };
init_function_group(subfunction_infos, count, "⎕RVAL");
N = 8;
desired_maxdepth= 4;
memset(state, 0, *sizeof*(state));
initstate(1, state, N); // <<< uses
initstate() instead of initstate_r()
*while*(desired_shape.get_rank() < MAX_RANK)
desired_shape.add_shape_item(1);
desired_ranks.push_back(0);
desired_types.push_back(0); // no chars
desired_types.push_back(1); // ints
desired_types.push_back(0); // no real
desired_types.push_back(0); // no complex
desired_types.push_back(0); // no nested
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
Value_P
Quad_RVAL::generator_state(*const*Value& B)
{
// expect an empty, 8, 16, 32, 64, 128, or 256 byte integer vector
//
*if* (B.get_rank() != 1) RANK_ERROR;
*const* ShapeItem new_N = B.element_count();
*if* (new_N != 0 && new_N != 8 && new_N != 32 &&
new_N != 64 && new_N != 128 && new_N != 256)
{
MORE_ERROR() << "bad new_N (aka. ⍴B) in generator_state()";
LENGTH_ERROR;
}
// always return the previous state
//
Value_P Z(N, LOC);
loop(n, N) Z->next_ravel_Int(state[n] & 0xFF);
Z->check_value(LOC);
*if*(new_N) // set generator state
{
// make sure that all values are bytes
//
loop(b, N)
{
*const* APL_Integer byte = B.get_cravel(b).get_int_value();
*if* ((byte < -256) || (byte > 255))
{
MORE_ERROR() << "Bad right argument B in 0 ⎕RVAL B,"
"expecting bytes (integers -256...255)";
DOMAIN_ERROR;
}
}
N = new_N;
loop(b, N)
{
state[b] = B.get_cravel(b).get_int_value();
}
setstate(state); // uses setstate() instead of setstate_r()
}
*return* Z;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
uint64_t
Quad_RVAL::rand17()
{
*const* int32_t rnd = random(); // uses random() instead of
random_r()
// the lower bits are less random, so we xor the upper 16 bits into
// the lower 16 bits and return them.
*return* (rnd ^ (rnd >> 16)) & 0x1FFFF;
}
//----------------------------------------------------------------------------
I have tested a build of GNU APL SVN 1922 and "reversed" the test
for the HAVE_LIBC in Quadf_RVAL.cc <http://quadf_rval.cc/> so
that the code would try to be compiled under macOS. Everything
related to ⎕RVAL seems to work in my limited testing (it at least
didn't crash the interpreter).
Is the use of random() instead of random_r(), etc. in the code an
oversight. Or is the documentation incorrect?
- Paul Rockwell
--
Mike Hall