gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problems Interfacing Modula-2 with GNU Readline library


From: Alice Osako
Subject: Re: Problems Interfacing Modula-2 with GNU Readline library
Date: Mon, 4 Mar 2024 14:33:06 -0500
User-agent: Mozilla Thunderbird

One minor error in the test code, in that I had somehow copied an older version of the code. The line 'Fin(input)' should be at the start of the loop, not the end.


Alice Osako:
I am working on a medium-sized project in Modula-2 (specifically, an implementation of the MAL interpreter - see https://github.com/kanaka/mal for details), and one of the soft requirements/recommended implementation details is editable input and input history. For this purpose, I intend to use the existing Readline library, and to this end I created a simple definition module as a binding.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DEFINITION MODULE FOR "C" readline;

FROM SYSTEM IMPORT ADDRESS;

EXPORT UNQUALIFIED readline, add_history;

PROCEDURE readline (prompt: ARRAY OF CHAR) : ADDRESS;

PROCEDURE add_history (line: ARRAY OF CHAR);

END readline.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

However, I am running into a problem when testing these bindings. When I run the following test program:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MODULE rl_test;

FROM SYSTEM IMPORT ADDRESS;

FROM DynamicStrings IMPORT String, Fin, Length,
                                                       InitStringCharStar,
                                                      CopyOut, Equal;

FROM StrIO IMPORT WriteString, WriteLn;

FROM readline IMPORT readline, add_history;

VAR
   input, exitCondition: String;
   temp: ARRAY [0..1024] OF CHAR;

BEGIN
   exitCondition := InitString("exit");
   WHILE NOT Equal(input, exitCondition) DO
      input := InitStringCharStar(readline("Write something: "));

      IF Length(input) > 0 THEN
         WriteString("You Wrote: ");
         CopyOut(temp, input);

         WriteString(temp);
         WriteLn;
         add_history(temp);
      ELSE
         WriteString("No input");
         WriteLn;
      END;
      Fin(input);
   END;

END rl_test.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I expected that this would result in something like the following:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Write something: foo
You Wrote: foo
Write something: bar
You Wrote: bar
Write something:
No input
Write something: bar
You Wrote: bar
Write something: quux
You Wrote: quux
Write something: exit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

However, the output I actually got was:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Write something: foo
Write something: bar
Write something:
Write something: bar
Write something: quux
Write something: exit
You Wrote: foo
You Wrote: bar
No input
You Wrote: bar
You Wrote: quux
You Wrote: exit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

So my issue is, why is the response not getting flushed until after the input is completed?

Oddly enough, when I add

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
FROM InOut IMPORT WriteCard;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

and insert this following the input but before the IF statement:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      WriteCard(Length(input), 3);
      WriteLn;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The result is different:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Write something: foo
  3Write something: bar

You Wrote: foo
  3Write something:

You Wrote: bar
  0Write something: bar

No input
  3Write something: quux

You Wrote: bar
  4Write something: exit

You Wrote: quux
  4
You Wrote: exit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Why this particular delayed interleaving is happening, and why the WriteLn is getting ignored,  is puzzling to me.

Is there some known issue with interfacing the C libraries, or the Readline library specifically, that I need to be aware of?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]