I'm running a constant loop of ReadLn to get command input. But when it comes to multithreading, I get an issue:
var command: string;
function ThreadTest(p: pointer) : ptrint;
begin
Delay(500);
WriteLn('THREAD TEST');
end;
{...}
BeginThread(#ThreadTest);
ReadLn(command);
'THREAD TEST' is written in the input field.
Is there any way to prevent this? I don't want to wait for the thread to finish to call ReadLn. Do I have to rewrite ReadLn using ReadKey? I'm using FreePascal with Crt and Windows.
EDIT: I need to write 'THREAD TEST' as a new line and move the ReadLn down 1 tcrtcoord, so 'THREAD TEST' is displayed properly. WriteLn works perfectly and as intended, unless called while ReadLn is in process.
Related
I was trying to print "Hello World", but I continue to get number 7 returned. Also, after the 7 is returned, I cannot run another file without restarting cmd window. If I hit enter key, the number increments by 1. Please explain why this is happening and possible ways to correct.
Put a / on a new line at the end of the file to terminate the PL/SQL anonymous block.
SET SERVEROUTPUT ON;
DECLARE
name VARCHAR2(20);
BEGIN
name := 'Hello World';
DBMS_OUTPUT.PUT_LINE(name);
END;
/
SQL/Plus has read your file but has not found the statement terminator for the PL/SQL block so it is continuing to ask for more input to complete the statement. It is expecting a / character on a new line (the 7th line of the statement, the first being DECLARE as the SET command is a different statement) and when you press the enter key then it moves on to line 8 of the statement and is still expecting the terminator character so asks for more input (and repeats for the 9th, 10th and 11th lines).
You could press / then enter in SQL/Plus but it would be better to fix the file so it contains complete statements.
I am working on reading a text file in vhdl. There are many examples on this, but I am curious why this minimal showcase example doesn't work in GHDL. It works in ModelSim (by Mentor).
Is this because of missing features in GHDL? (I did not find anything in docs/ github issues)
Is this because of wrong standard that I am using without knowing?
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use STD.textio.all;
entity test is
end test;
architecture behavioral of test is
file input : text;
begin
process
variable line_in : line;
begin
file_open(input, "input.txt");
while not endfile(input) loop
readline(input, line_in);
end loop;
wait for 100 ns;
end process;
end behavioral;
The output I get is:
./test:error: cannot open file "input.txt"
This means, there is no file/cannot be opened, but the file exists with correct access rights (proven in Modelsim). I tried this with full file name, too.
I'm using GHDL 0.37 on Linux with these flags:
--ieee=synopsys --std=08
If
file input : text;
is replaced with
file input : text open read_mode is "input.txt";
and
file_open(input, "input.txt");
is removed it works in GHDL.
However, I still don't know why the previous version did not work.
The example code is expected to fail. Note the lack of a procedure file_close call.
After the execution of the wait for 100 ns; wait statement the execution of the process statement will resume in a future simulation cycle. The statements in a process are executed in order and after the last statement (the wait statement) the first statement
file_open(input, "input.txt");
will be executed again.
Without an intervening file_close call a subsequent file_open call will fail.
IEEE Std 1076-2008
10.2 Wait statement
The timeout clause specifies the maximum amount of time the process will remain suspended at this wait statement. If no timeout clause appears, the timeout clause for (STD.STANDARD.TIME'HIGH – STD.STANDARD.NOW) is assumed. It is an error if the time expression in the timeout clause evaluates to a negative value.
11.3 Process statement
The execution of a process statement consists of the repetitive execution of its sequence of statements. After the last statement in the sequence of statements of a process statement is executed, execution will immediately continue with the first statement in the sequence of statements.
5.5.2 File operations:
In the second form of FILE_OPEN, the value returned through the Status parameter indicates the results of the procedure call:
— A value of OPEN_OK indicates that the call to FILE_OPEN was successful. If the call to FILE_OPEN specifies an external file that does not exist at the beginning of the call, and if the access mode of the file object passed to the call is write-only, then the external file is created.
— A value of STATUS_ERROR indicates that the file object already has an external file associated with it.
— A value of NAME_ERROR indicates that the external file does not exist (in the case of an attempt to read from the external file) or the external file cannot be created (in the case of an attempt to write or append to an external file that does not exist). This value is also returned if the external file cannot be associated with the file object for any reason.
— A value of MODE_ERROR indicates that the external file cannot be opened with the requested Open_Kind.
The first form of FILE_OPEN causes an error to occur if the second form of FILE_OPEN, when called under identical conditions, would return a Status value other than OPEN_OK.
The question use of the file_open procedure call is of the first form. The second form would fail returning a Status parameter value of STATUS_ERROR, already associating an external file with the file object input.
The fix for that would be to transform the wait statement to prevent the process from continuing to execute:
wait; -- wait for 100 ns;
end process;
or provide an explicit file_close call so a subsequent file_open call would succeed. (This would cause a lot of host activity for no useful purpose.)
The modified code could look like:
-- library IEEE;
-- use IEEE.STD_LOGIC_1164.all; -- NOT USED
use STD.textio.all;
entity test is
end test;
architecture behavioral of test is
file input : text;
begin
process
variable line_in : line;
begin
file_open(input, "input.txt");
while not endfile(input) loop
readline(input, line_in);
write (OUTPUT, line_in.all & LF);
end loop;
wait; -- wait for 100 ns; -- EXECUTE ONCE
end process;
end behavioral;
Yields:
%% ghdl -a --ieee=synopsys --std=08 test.vhdl
%% ghdl -e --ieee=synopsys --std=08 test
%% ghdl -r --std=08 test
some text
more text
yet some more text
getting boring
%%
Where a write to the file OUTPUT (the console) echos the contents of each line found in input.txt. Note that the end of line is removed by the readline procedure call and reintroduced to the string being written to OUTPUT.
So why does the different file declaration succeed?
architecture file_declaration of test is
-- file input : text;
file input: text open read_mode is "input.txt";
begin
process
variable line_in: line;
begin
-- file_open(input, "input.txt");
while not endfile(input) loop
readline(input, line_in);
write (OUTPUT, line_in.all & LF);
end loop;
wait for 100 ns;
end process;
end architecture file_declaration;
There's only one call to file_open, an implicit call during elaboration of the file declaration (6.4.2.5 File declarations). The file remains open yet there are no remaining lines to read, determined by the endfile call. Here the endfile call would occur every 100 ns, which would likely result in your CPU utilization to increase as test executes until TIME'HIGH is reached. Performing the endfile call would result in host file operations resulting in suspension and resumption of the ghdl model execution. An effective test of only making endfile procedure calls.
A wait statement (10.2) without a timeout clause (for 100 ns) will wait until TIME'HIGH effective ending the simulation without any intervening signal events or other process suspensions and resumptions or making TIME'HIGH/100 ns - 1 endfile procedure calls, each involving suspension and resumption of the shown process statement.
You could also specify a simulation stop time on ghdl's command line, matching the usage in Modelsim most likely:
%% ghdl -a --ieee=synopsys --std=08 test.vhdl
%% ghdl -e --ieee=synopsys --std=08 test
%% ghdl -r --std=08 test --stop-time=300ns
some text
more text
yet some more text
getting boring
./test:info: simulation stopped by --stop-time #300ns
%%
Host file operations can incur a significant execution time penalty. If you were to assign the read values to a signal or variable of a composite (array or record) type object they can be reused without waiting on host file operations.
I've made this program and I was wondering why oracle prompts for input even when it does not run the 'D' case (when 'A' is imputed for example).
SET SERVEROUTPUT ON;
ACCEPT p_user_letter PROMPT 'Enter an option';
DECLARE
v_user_letter VARCHAR2(200) := UPPER('&p_user_letter');
BEGIN
CASE v_user_letter
when 'A' then dbms_output.put_line('A pressed');
when 'D' then new_customer('&userEntered');
else dbms_output.put_line('Other');
END CASE;
END;
/
CREATE OR REPLACE PROCEDURE new_customer
(ccName IN Varchar2)
IS
BEGIN
dbms_output.put_line('Ran procedure');
END new_customer;
From the error message it seems like it runs a new and old version of declare which forces all uninitialized prompts to have a value, but i'm not certain and could not find out why online.
Both new and old running
('&userEntered'); is a substitution variable.
The substitution variables are not a part of SQL, this is a feature of SQL-Plus client, it is also supported by SQL-Developer.
When you hit Enter (or Run icon in SQL-Developer), SQL-Plus first analyses your script. When it finds &xxx string in your script, then prompts the user for a value. When the user enters the value then SQL-Plus substitutes (replaces) &xxx with the value entered by the user.
When SQL-Plus substitutes all substitution variables, then it starts to execute this script - that is, it sends SQL commands from the script to the Oracle Database for execution.
You can think of the variable substitution in SQL-Plus as a kind of macro preprocesing.
I am working with Vivado simulator.
I would like to know if it is possible to suppress the time messages in the Tcl console. They are printed with the note entry:
report "LED1 is turned on" severity note;
results int:
Note: LED1 is turned on
Time: 4477500 ps Iteration: 6 Process: /testbench/\GEN(1)/line__280 File: H:/Image/Image.srcs/sim_1/new/tb.vhd
Can I get rid of this time entry?
Thank you so for this post it really helped me.
It is not straight forward though.
You need to mark them as a string unfortunately. So in vivado the following will work
use STD.TextIO.all;
procedure test is
variable LineBuffer : LINE;
begin
write(LineBuffer, string'("test message"));
writeline(output, LineBuffer);
end procedure;
Please note its not in brackets its with an apostrophe.
No, the report and assert format is fixed.
But, you can write to STDOUT from VHDL. These messages are displayed without time information in the simulator console (between other messages).
Example for writing to STDOUT:
use STD.TextIO.all;
procedure test is
variable LineBuffer : LINE;
begin
write(LineBuffer, "test message");
writeline(output, LineBuffer);
end procedure;
Source: https://github.com/VLSI-EDA/PoC/blob/master/src/sim/sim_protected.v08.vhdl#L150-L226
Screenshot from iSim:
The output from Vivado Simulator should be similar.
I have some scripts that get run often, always from within a connected SQLPlus session.
I need a way to exit the script when an error occurs, without disconnecting or exiting SQLPlus itself. 100% of the time, when an error occurs, the connected DBA will need to issue one or more commands into the session. 100% of the time, when an error occurs, there are other SQLPlus statements (and thus must be outside of a BEGIN..END;) later on in the script that must not be executed or serious problems could arise.
NOTE: If you suggest WHENEVER SQLERROR EXIT then you didn't read the above text. That will disconnect and exit SQLPlus in addition to the script, which is not acceptable behavior.
I've found an interesting idea here which, when combined with spencer7593's answer, will get me selective sub-script calling, to which I can pass the PL/SQL output values. To wit:
VAR continue number;
EXEC :continue := 1;
BEGIN
SELECT some_bool_test() INTO :continue FROM dual;
END;
SET termout OFF
COLUMN script_name NEW_VALUE v_script_name
SELECT decode(:continue, 1, 'run_stuff.sql', 'skip.sql') script_name FROM dual;
SET termout ON
#&v_script_name :some_other_values
Where skip.sql is an empty text file.
UPDATE: I've moved most of this into a RUN.SQL file, where I pass in the boolean (0 or 1) as &1, the script name to call on success as &2, and then any other expected parameters to pass to the called script. Thus, it ends up looking something like this:
VAR continue number;
EXEC :continue := 1;
BEGIN
SELECT some_bool_test() INTO :continue FROM dual;
END;
#run.sql :continue 'run_stuff.sql' :some_other_values
It's not possible.
SQLPlus doesn't provide that level of control over the execution of a script.
Obviously, you'd need to AVOID using the WHENEVER SQLERROR EXIT ... command.
It's possible to gain conditional control over which SQL statements do or do not get executed as a result of raised exceptions (errors) using PL/SQL. But that doesn't address SQLPlus commands (which cannot be executed from within a PL/SQL block.)
DECLARE
lb_continue BOOLEAN;
BEGIN
lb_continue := TRUE;
BEGIN
sql statement
EXCEPTION
WHEN OTHERS THEN
lb_continue = FALSE;
END;
IF lb_continue THEN
BEGIN
sql statements
EXCEPTION
WHEN OTHERS THEN
lb_continue := FALSE;
END;
END;
Of course, that approach has it's own limitations and issues. Any DDL statements would need to be called dynamically; the easiest way to do that is an EXECUTE IMMEDIATE statement.
The biggest issue (in your case) is that it's not possible to execute SQLPlus commands from inside a PL/SQL block.
You can't exit the script and stay in SQL*Plus, but you can stop executing things. It isn't pretty, but assuming you can modify the script to add the control flow then you can just about do this with bind variable.
set serveroutput on
var flag char;
exec :flag := 'Y';
begin
if :flag != 'Y' then
raise program_error;
end if;
dbms_output.put_line('Doing some work');
/* Check for some error condition */
if 0 != 1 then
raise program_error;
end if;
/* Only reach this if earlier statements didn't fail
* but could wrap in another flag check if needed */
dbms_output.put_line('Doing some more work');
exception
when program_error then
dbms_output.put_line(sqlerrm);
:flag := 'N';
when others then
/* Real exception handling, obviously */
dbms_output.put_line(sqlerrm);
:flag := 'N';
end;
/
-- DML only does anything if flag stayed Y
select sysdate from dual
where :flag = 'Y';
-- Optional status message at the end of the script, for DBA info
set feedback off
set head off
select 'Something went wrong' from dual where :flag != 'Y';
set feedback on
set head on
When executed:
SQL> #script
PL/SQL procedure successfully completed.
Doing some work
ORA-06501: PL/SQL: program error
PL/SQL procedure successfully completed.
no rows selected
Something went wrong
SQL>
Any PL/SQL blocks in the script can check the flag status at the start, and raise program_error (just as a handy pre-defined exception) to jump back out. Anything that errors inside a PL/SQL block can update the bind variable flag, either directly or in an exception handler. And any non-PL/SQL DML can have an additional where clause to check the flag status, so if it's been set to N by the time that statement is reached, no work is done. (For an insert I guess that would mean not using the values form).
What this can't do is deal with any errors from plain SQL statements, but I'm not sure if that's an issue. If it is then those might need to be changed to dynamic SQL inside a PL/SQL block.
I know its old, but these two instructions at the very begining of the SQL script do the work:
WHENEVER SQLERROR EXIT FAILURE ROLLBACK
WHENEVER OSERROR EXIT FAILURE ROLLBACK