Inputs expected on function call in structured text - user-defined-functions

I'm working on a project with RightWON Configuration Suite. I use structured text to code and create functions (UDFB). My problem is that when I start the simulation, I get an error message telling me that there are inputs expected on the line where my function is called.
Here are my variables:
Here is the main code:
nombre_power_source_on := 1;
gd1_synchro := FALSE;
gd2_synchro := FALSE;
mgset_synchro := FALSE;
result := MasterSlaveFunction(nombre_power_source_on, gd1_synchro, gd2_synchro, mgset_synchro);
gd1_sm := result.gd1_sm;
gd2_sm := result.gd2_sm;
mgset_sm := result.mgset_sm;
Here is the MasterSlaveFunction function:
IF nombre_power_source_on <= 1 THEN
gd1_sm := 1;
gd2_sm := 1;
mgset_sm := 1;
ELSE
IF gd1_synchro = TRUE THEN
gd2_sm := 0;
mgset_sm := 0;
ELSIF gd2_synchro = TRUE THEN
gd1_sm := 0;
mgset_sm := 0;
ELSIF mgset_synchro = TRUE THEN
gd1_sm := 0;
gd2_sm := 0;
END_IF;
END_IF;
And here are the inputs and outputs of the function:

Related

Error: BREAK not allowed in for looping pascal

I try to create a for looping for my Bubble Sort Algorithm and use break as a condition if there is no more number to be sorted anymore. But then the compiler said that BREAK not allowed. Here is my code
Procedure Sort(var data : arr; j : integer);
var
temp: integer;
begin
temp := data[j];
data[j] := data[j + 1];
data[j + 1] := temp;
end;
Procedure sortDescending(var data : arr; n : integer);
var
i, j : integer;
marker : boolean;
begin
for i := 1 to n do
marker := false;
begin
for j := 1 to n do
begin
if(data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if(marker = false) then
begin
break;
end;
end;
end;
Here's your code.
for i := 1 to n do
marker := false;
begin
for j := 1 to n do
begin
if(data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if(marker = false) then
begin
break;
end;
end;
Let's add some whitespace after loops and indentation to make the issue clearer.
for i := 1 to n do
marker := false;
begin
for j := 1 to n do
begin
if (data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if (marker = false) then
begin
break;
end;
end;
Which is equivalent to:
for i := 1 to n do
marker := false;
for j := 1 to n do
begin
if (data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if (marker = false) then
begin
break;
end;
The break is not within a loop.
You likely meant to put begin before marker := false;.
for i := 1 to n do
begin
marker := false;
for j := 1 to n do
begin
if (data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if (marker = false) then
begin
break;
end;
end;

Program behaving differently in FPC and ObjFPC

Following is a program in lazarus to perform RC4 encryption and decryption when given a string. When the compiler directive {$mode fpc} is used and the string 123 is entered it crashes with External: SIGSEGV. However there is no crash when inputting the same string in {$mode objfpc}. Another inconsistency is that in {$mode objfpc} the program raises the exception External: SIGSEGV again with the input of hellow.
//{$mode fpc}
{$mode objfpc}
program project1;
uses
sysutils, strutils;
type
myArray = array[0..255] of integer;
dynamicArray = array of integer;
dynamicArrayString = array of string;
const
key = 'qwertyui';
var
plaintext : string;
function KSA(const key: string): myArray;
var
i, j, key_length, temp: integer;
S : myArray;
begin
key_length := length(key);
j := 0;
for i := Low(S) to High(S) do
S[i] := i;
for i := Low(S) to High(S) do
begin
j := ((j + S[i] + ord(key[i mod key_length + 1])) mod 256);
temp := S[i];
S[i] := S[j];
S[j] := temp;
end;
KSA := S;
end;
function PRGA(S : myArray; n : integer) : dynamicArray;
var
i, j, K, temp, sizeOfArray : integer;
key : dynamicArray;
begin
i := 0;
j := 0;
K := 0;
temp := 0;
sizeOfArray := n - 1;
SetLength(key, sizeOfArray);
while n > 0 do
begin
n := n - 1;
i := (i + 1) mod 256;
j := (j + S[i]) mod 256;
temp := S[i];
S[i] := S[j];
S[j] := temp;
K := S[(S[i] + S[j]) mod 256];
key[i-1] := K;
end;
PRGA := key;
end;
procedure getPlaintext;
begin
readln(plaintext);
end;
function encrypt : string;
var
sizeOfArray, i : integer;
cipherString : string;
cipher, keystream: dynamicArray;
S : myArray;
begin
S := KSA(key);
keystream := PRGA(S, length(plaintext));
sizeOfArray := 0;
for i := 0 to (length(plaintext) - 1) do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(cipher, sizeOfArray);
cipher[i] := (keystream[i]) xor (ord(plaintext[i + 1]));
end;
cipherString := '';
for i := 0 to High(cipher) do
cipherString := cipherString + IntToHex(cipher[I], 2);
encrypt := cipherString;
end;
function stringToHex(cipherString : string) : dynamicArrayString;
var
sizeOfArray, i: integer;
DecryptArrayString : dynamicArrayString;
begin
sizeOfArray := 0;
i := 0;
// Turn the string into an array of hex
while length(cipherString) > 0 do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(DecryptArrayString, sizeOfArray);
DecryptArrayString[i] := cipherString[1] + cipherString[2];
i := i + 1;
cipherString := rightstr(cipherString, length(cipherString) - 2);
end;
stringToHex := DecryptArrayString;
end;
function hexToDecimal(DecryptArrayString : dynamicArrayString) : dynamicArray;
var
sizeOfDecryptArrayInt, i : integer;
DecryptArrayInt : dynamicArray;
begin
sizeOfDecryptArrayInt := 0;
// Hex to decimal
for i := 0 to high(DecryptArrayString) do
begin
sizeOfDecryptArrayInt := sizeOfDecryptArrayInt + 1;
SetLength(DecryptArrayInt, sizeOfDecryptArrayInt);
DecryptArrayInt[i] := Hex2Dec(DecryptArrayString[i]);
end;
hexToDecimal := DecryptArrayInt;
end;
function decrypt(DecryptArrayInt : dynamicArray) : string;
var
DecryptedString : string;
S : myArray;
keystream, Decrypted : dynamicArray;
sizeOfArray, i : integer;
begin
sizeOfArray := 0;
for i := 0 to high(DecryptArrayInt) do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(Decrypted, sizeOfArray);
S := KSA(key);
keystream := PRGA(S, length(plaintext));
Decrypted[i] := (keystream[i] xor DecryptArrayInt[i]);
end;
decryptedString := '';
// Turn array to string
for i := 0 to high(Decrypted) do
decryptedString := decryptedString + chr(Decrypted[i]);
decrypt := decryptedString;
end;
procedure encryptDecrypt;
var
cipherString, DecryptedString : string;
DecryptArrayString : dynamicArrayString;
DecryptArrayInt : dynamicArray;
begin
cipherString := encrypt;
writeln(cipherString);
DecryptArrayString := stringToHex(cipherString);
DecryptArrayInt := hexToDecimal(DecryptArrayString);
DecryptedString := decrypt(DecryptArrayInt);
writeln(DecryptedString);
end;
begin
getPlaintext;
encryptDecrypt;
readln;
end.
I've not been able to find the many specific cases that makes the program crash apart from a string of any three characters will always crash in {$mode fpc} but not in {$mode objfpc}
You should debug (and watch) your code so any error can be traced more easily. Use the FP IDE, it helps a lot.
Meanwhile, watch this line:
keystream := PRGA(S, length(plaintext));
And inside the PRGA function watch these lines:
sizeOfArray := n - 1;
SetLength(key, sizeOfArray);
What's wrong here? Well, suppose "plaintext" has only 1 character. So, "Length(plaintext)"=1, right? In PRGA you do "sizeOfArray:= n-1;", so sizeOfArray = 0. When you do SetLength, "Key" will be NIL because you're indicating a zero indexes length. Later, on loop, you have:
key[i-1] := K;
the program will fail because you are accessing at index 0 and the Key variable is NIL.
Careful: On "SetLength(key, sizeOfArray);" valid indexes for key are in range [0..sizeOfArray-1], but sizeOfArray must be at least 1 to be valid (sizeOfArray >= 1).
So, you should check your PRGA function. It's up to you to find the definitive solution. Don't give up. Good luck!

Convert a slice of strings into slice of float32

In my program, I add a string of numbers (ex: 54 43.3 -43.2) to a slice via bufio scanner. Then I want to split the slice at each space into another slice to convert it to float32. Here is what i have:
var newSlice []float32
sliceScan = scanner.Text()
s := strings.Split(sliceScan, " ")
for i:= 0; i < len(s); i+=1 {
newSlice[i] = (float32) s[i]
}
when I run this I get this error:
syntax error: unexpected s at the end of statement
You can use strconv.ParseFloat:
var newSlice []float32
sliceScan = scanner.Text()
s := strings.Split(sliceScan, " ")
for i:= 0; i < len(s); i+=1 {
f64, err := strconv.ParseFloat(s[i], 32)
newSlice = append(newSlice, float32(f64))
}
or probably better:
sliceScan = scanner.Text()
s := strings.Split(sliceScan, " ")
newSlice := make([]float32, len(s), len(s))
for i:= 0; i < len(s); i+=1 {
f64, err := strconv.ParseFloat(s[i], 32)
newSlice[i] = float32(f64)
}

Why the code returns negative values in Codility test case?

The Codility problem and test case are shown in:here
The code written in golang:
func Solution(A []int, B []int) []int {
result := make([]int, len(A))
step := make([]int, len(A)+1)
step[0] = 1
step[1] = 1
for i := 2; i <= len(A); i++ {
step[i] = step[i-1] + step[i-2]
}
for i := 0; i < len(A); i++ {
result[i] = int(int32(step[A[i]]) % int32(math.Pow(2, float64(B[i]))))
// result[i] = step[A[i]] & (1<<uint(B[i]) - 1)
}
return result
}
The result[i] = step[A[i]] & (1<<uint(B[i]) - 1) passes all the cases. But result[i] = int(int32(step[A[i]]) % int32(math.Pow(2, float64(B[i])))) or result[i] = step[A[i]] % int(math.Pow(2, float64(B[i]))) results some negative numbers.
It seems something goes overflow. Would anyone know reason? Thanks!
For some input, you're converting a value in the range [1<<31, 1<<32) to an int32.
http://play.golang.org/p/6HYPXY9Kjb
a := int64(1 << 31)
b := int64(1<<32 - 1)
// int32(a) == -2147483648
// int32(b) == -1
Depending on how your algorithm is supposed to work, you need to expand the range to use int64, or use a uint32, which will truncate the value but remain positive.

Correct way to do non overlapped communication via serial port (COM)

I am using Delphi XE2 and I try to communicate with some device via serial port. Communication should be straight forward, but I have some problems. The device communication protocol is as follows:
I (master) send frame starting with ":" and ending with CRLF.
The device (slave) sends response in the same format (starting with ":" and ending with CRLF).
I am using WinAPI and non overlapped IO. The problem I have is that, very often I receive #0 chars as response from the device. I am sure the problem is on my side, because I can use device provider application, and I can see that communication goes fine.
Here is how I setup my COM port:
Result := False;
FFileHandle := CreateFile('COM3', GENERIC_READ OR GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);
if FFileHandle = INVALID_HANDLE_VALUE then
Exit;
if not GetCommState(FFileHandle, DCB) then
Exit;
DCB.BaudRate := ASettings.BaudRate;
DCB.Flags := 1 OR // BINARY
(DTR_CONTROL_ENABLE shl 4) OR
(RTS_CONTROL_ENABLE shl 12);
DCB.XonLim := 100; // transmit XON threshold
DCB.XoffLim := 100; // transmit XOFF threshold
DCB.ByteSize := 8; // number of bits/byte, 4-8
DCB.Parity := 0; // 0-4=no,odd,even,mark,space
DCB.StopBits := ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
DCB.XonChar := #1; // Tx and Rx XON character
DCB.XoffChar := #2; // Tx and Rx XOFF character
DCB.ErrorChar := #$FF; // error replacement character
DCB.EofChar := #$0A; // end of input character
DCB.EvtChar := #$0A; // received event character
if not SetCommState(FFileHandle, DCB) then
Exit;
if not SetCommMask(FFileHandle, EV_RXCHAR OR EV_TXEMPTY OR EV_RXFLAG) then
Exit;
Timeouts.ReadIntervalTimeout := 1200;
Timeouts.ReadTotalTimeoutMultiplier := 1;
Timeouts.ReadTotalTimeoutConstant := 1200;
Timeouts.WriteTotalTimeoutMultiplier := 0;
Timeouts.WriteTotalTimeoutConstant := 0;
if not SetCommTimeouts(FFileHandle, Timeouts) then
Exit;
if not PurgeComm(FFileHandle, PURGE_TXABORT OR PURGE_RXABORT OR PURGE_TXCLEAR OR PURGE_RXCLEAR) then
Exit;
if not ClearCommError(FFileHandle, Errors, #ComStat) then
Exit;
if not SetupComm(FFileHandle, 1024, 1024) then
Exit;
Result := True;
Here is how I do write:
function TCOMPortWrapper.Write(const AFrame: AnsiString): TComPortWriteRes;
var
Written: Cardinal;
Err: Cardinal;
Stat: TComStat;
Mask: Cardinal;
begin
Result := CPW_ERROR;
ClearCommError(FFileHandle, Err, #Stat);
if not IsOpened then
Exit;
if not WriteFile(FFileHandle, AFrame[1], Length(AFrame), Written, nil) then
Exit;
Mask := EV_TXEMPTY;
if not WaitCommEvent(FFileHandle, Mask, nil) then
Exit;
ClearCommError(FFileHandle, Err, #Stat);
Result := CPW_OK;
end;
And finally here it is how I do reads:
function TCOMPortWrapper.Read(out Frame: AnsiString): TComPortReadRes;
var
S: AnsiString;
BytesRead: Cardinal;
Mask: Cardinal;
begin
Result := CPR_ERROR;
if not IsOpened then
Exit;
SetLength(S, 4096);
Mask := EV_RXFLAG;
if not WaitCommEvent(FFileHandle, Mask, nil) then
Exit;
if not ReadFile(FFileHandle, S[1], Length(S), BytesRead, nil) then
Exit;
SetLength(S, BytesRead);
Frame := S;
Result := CPR_OK;
end;
As I mentioned above, in reads instead of getting actual frame I do get string of #0 chars. I think, that my mistake might be with WaitCommEvent API calls, as I am very new to serial communication.
Thanks for help!
Maybe you forgot the "#": ReadFile(FFileHandle, # S[1], Length(S), BytesRead, nil)
I'm doing like this to read string from COM:
constructor TSerialPort.Create(const APortName: String);
begin
inherited Create;
FPortHandle := INVALID_HANDLE_VALUE;
FPortName := APortName;
FDCB.DCBlength := SizeOf(DCB);
FDCB.BaudRate := CBR_19200;
FDCB.Flags := MakeCommFlags(True, False, True, True, DTR_CONTROL_DISABLE,
False, False, False, False, False, False, RTS_CONTROL_DISABLE, False);
FDCB.wReserved := 0;
FDCB.XonLim := 2048;
FDCB.XoffLim := 512;
FDCB.ByteSize := 8;
FDCB.Parity := NOPARITY;
FDCB.StopBits := ONESTOPBIT;
FDCB.XonChar := #0;
FDCB.XoffChar := #0;
FDCB.ErrorChar := #0;
FDCB.EofChar := #255;
FDCB.EvtChar := #0;
FDCB.wReserved1 := 0;
FCTO.ReadIntervalTimeout := 0;
FCTO.ReadTotalTimeoutMultiplier := 20;
FCTO.ReadTotalTimeoutConstant := 500;
FCTO.WriteTotalTimeoutMultiplier := 10;
FCTO.WriteTotalTimeoutConstant := 200;
FEOSChar := #13;
end;
function TSerialPort.Open: Boolean;
begin
Result := False;
if FPortHandle <> INVALID_HANDLE_VALUE then
Close;
FPortHandle := CreateFile(PChar('\\.\'+FPortName), GENERIC_READ or GENERIC_WRITE, 0,
nil, OPEN_EXISTING, 0, 0);
if FPortHandle <> INVALID_HANDLE_VALUE then
begin
// setup device buffers
SetupComm(FPortHandle, 2048, 2048);
Flush; // purge any information in the buffer
Result := True;
end;
end;
function TSerialPort.ReadString(var S: SysUtils.TBytes): Boolean;
const
MAX_BUF = 255;
var
B: Byte;
iCounter: Integer;
begin
Result := True;
B := 0;
SetLength(S, MAX_BUF);
ZeroMemory(#S[0], Length(S));
iCounter := 0;
while (B <> Ord(FEOSChar)) and Result and (iCounter < MAX_BUF) do
begin
Result := Read(B, 1);
if (B <> Ord(FEOSChar)) and Result then
begin
S[iCounter] := B;
Inc(iCounter);
end;
end;
if Result then
begin // delete leading zeros
while (Length(S) > 0) and (S[0] = 0) do
begin
for iCounter := 0 to Length(S)-2 do
S[iCounter] := S[iCounter+1];
SetLength(S,Length(S)-1);
end;
end
else
SetLength(S, 0);
end;
function TSerialPort.Read(var inbuf; inlen: DWORD): Boolean;
var
dwBytesRead: DWORD;
begin
Result := False;
if FPortHandle = INVALID_HANDLE_VALUE then
Exit;
dwBytesRead := 0;
Result := ReadFile(FPortHandle, inbuf, inlen, dwBytesRead, nil);
end;
FEOSChar end of string byte/char. To get string from TBytes you can use SysUtils.StringOf() function
upd:
function MakeCommFlags(fBinary, fParity, fOutxCtsFlow, fOutxDsrFlow: Boolean;
fDtrControl: Byte; fDsrSensitivity, fTXContinueOnXoff, fOutX, fInX,
fErrorChar, fNull: Boolean; fRtsControl: Byte;
fAbortOnError: Boolean): DWORD;
begin
Result := 0;
fDtrControl := fDtrControl and $03;
fRtsControl := fRtsControl and $03;
Result := Result or (Byte(fBinary) shl 0);
Result := Result or (Byte(fParity) shl 1);
Result := Result or (Byte(fOutxCtsFlow) shl 2);
Result := Result or (Byte(fOutxDsrFlow) shl 3);
Result := Result or (Byte(fDtrControl) shl 4);
Result := Result or (Byte(fDsrSensitivity) shl 6);
Result := Result or (Byte(fTXContinueOnXoff) shl 7);
Result := Result or (Byte(fOutX) shl 8);
Result := Result or (Byte(fInX) shl 9);
Result := Result or (Byte(fErrorChar) shl 10);
Result := Result or (Byte(fNull) shl 11);
Result := Result or (Byte(fRtsControl) shl 12);
Result := Result or (Byte(fAbortOnError) shl 14);
end;

Resources