How do I iterate over a MULTI_SZ string in Inno Setup? - scripting

How do I iterate over a MULTI_SZ string in Inno Setup Pascal scripting?
e.g. over values returned by RegQueryMultiStringValue

Here's the code to do it:
var
I,StartPos:Integer;
MultiSzStr,Element:String;
...
StartPos := 1;
for I:= 1 to Length(MultiSzStr) do
begin
if MultiSzStr[I] = #0 then
begin
Element := Copy(MultiSzStr, StartPos, I - StartPos);
{ do something with the element }
StartPos := I + 1;
end;
end;

Related

ORACLE SQL function to return JSON response

I have table like below. I am trying to pull all BRKPK_CNTNR_ID, SSP_Q with respect to each OVRPK_CNTNR_ID
enter image description here
Below query runs fine and produces desired result.
DECLARE
json_objects JSON_OBJECT_LIST := JSON_OBJECT_LIST() ;
counter NUMBER := 1;
BEGIN
FOR ovrpk_detail IN (SELECT OVRPK_CNTNR_ID ,BRKPK_CNTNR_ID,ITEM_DISTB_Q FROM OVRPK_DET od WHERE od.OVRPK_CNTNR_ID='92000000356873110552') LOOP
begin
json_objects.extend;
json_objects(counter) :=JSON_UTIL.JSON_OBJECT(
JSON_ATTRIBUTE_LIST(
JSON_UTIL.JSON_ATTRIBUTE('over_pack_container_id',ovrpk_detail.OVRPK_CNTNR_ID),
JSON_UTIL.JSON_ATTRIBUTE('break_pack_container_id',ovrpk_detail.BRKPK_CNTNR_ID),
JSON_UTIL.JSON_ATTRIBUTE('item_distributed_quantity',ovrpk_detail.ITEM_DISTB_Q)
));
counter := counter+1;
END;
END LOOP;
dbms_output.put_line( JSON_UTIL.JSON_ARRAY(json_objects));
END;
I am expecting is to create function that takes OVRPK_CNTNR_ID as input and returns JSON_OBJECT_LIST as output.
Here is my query I tried.
CREATE OR REPLACE FUNCTION get_json_objects(ovrk_cntnr_id IN CHAR)
RETURN JSON_OBJECT_LIST IS
json_objects JSON_OBJECT_LIST := JSON_OBJECT_LIST();
BEGIN
DECLARE counter NUMBER := 1;
FOR ovrpk_detail IN (SELECT OVRPK_CNTNR_ID ,BRKPK_CNTNR_ID FROM OVRPK_DET od WHERE od.OVRPK_CNTNR_ID= ovrk_cntnr_id) LOOP
begin
json_objects.extend;
json_objects(counter) :=JSON_UTIL.JSON_OBJECT(
JSON_ATTRIBUTE_LIST(
JSON_UTIL.JSON_ATTRIBUTE('over_pack_container_id',ovrpk_detail.OVRPK_CNTNR_ID),
JSON_UTIL.JSON_ATTRIBUTE('break_pack_container_id',ovrpk_detail.BRKPK_CNTNR_ID)
));
counter := counter+1;
END;
END LOOP;
RETURN json_objects;
END;
DECLARE
json_return_object JSON_OBJECT_LIST;
ovrk_cnt_i char := '92000000356873110552'
BEGIN
json_return_object := get_json_objects(ovrk_cnt_i);
dbms_output.put_line('JSON Object is: ' || json_return_object);
END;
I am missing something, would anyone help me to resolve this issue? Thank you
Note: I am using Oracle 12.c database which does not support JSON however, JSON_UTIL is library written internally to address same
We do not have your packages or functions so this is difficult to test.
Your code has a DECLARE without a corresponding BEGIN or END. If you get rid of all the unnecessary DECLARE/BEGIN/END statements then you can simplify it to:
CREATE OR REPLACE FUNCTION get_json_objects(
ovrk_cntnr_id IN CHAR
)
RETURN JSON_OBJECT_LIST
IS
json_objects JSON_OBJECT_LIST := JSON_OBJECT_LIST();
counter NUMBER := 1;
BEGIN
FOR ovrpk_detail IN (
SELECT OVRPK_CNTNR_ID,
BRKPK_CNTNR_ID
FROM OVRPK_DET
WHERE OVRPK_CNTNR_ID = ovrk_cntnr_id
) LOOP
json_objects.extend;
json_objects(counter) :=JSON_UTIL.JSON_OBJECT(
JSON_ATTRIBUTE_LIST(
JSON_UTIL.JSON_ATTRIBUTE('over_pack_container_id',ovrpk_detail.OVRPK_CNTNR_ID),
JSON_UTIL.JSON_ATTRIBUTE('break_pack_container_id',ovrpk_detail.BRKPK_CNTNR_ID)
)
);
counter := counter+1;
END LOOP;
RETURN json_objects;
END;
/
If your package functions are callable from SQL then you should be able to simplify it further to:
CREATE OR REPLACE FUNCTION get_json_objects(
i_ovrpk_cntnr_id IN OVRPK_DET.OVRPK_CNTNR_ID%TYPE
) RETURN JSON_OBJECT_LIST
IS
json_objects JSON_OBJECT_LIST;
BEGIN
SELECT JSON_UTIL.JSON_OBJECT(
JSON_ATTRIBUTE_LIST(
JSON_UTIL.JSON_ATTRIBUTE('over_pack_container_id', OVRPK_CNTNR_ID),
JSON_UTIL.JSON_ATTRIBUTE('break_pack_container_id', BRKPK_CNTNR_ID)
)
)
BULK COLLECT INTO json_objects
FROM OVRPK_DET
WHERE OVRPK_CNTNR_ID = i_ovrpk_cntnr_id;
RETURN json_objects;
END;
/
DECLARE
json_return_object JSON_OBJECT_LIST;
ovrk_cnt_i OVRPK_DET.OVRPK_CNTNR_ID%TYPE := '92000000356873110552'
BEGIN
json_return_object := get_json_objects(ovrk_cnt_i);
dbms_output.put_line('JSON Object is: ' || json_return_object);
END;
/

How to sum 1+2^2+3^3+...n^n in pascal?

I want to sum that thing but only use the 'for loop' (no power functions). I've already created a loop that generates powers:
Program powers;
Var
i, n, result : integer;
writeln('enter N'), read(n);
BEGIN
Result := 1;
for i := 1 to n do
begin
Result := Result * n;
end;
writeln('result=',result);
END.
But I neither have any idea on how to make that code generate multiple powers ( this code only generates n^n) nor how to make a loop that sums them together.
It's best to break problems down into smaller problems. In this case, you may wish to have a pow function to handle the exponentiation for you.
Hopefully the pow function is acceptable if it's not a library function.
function pow(n, exp : integer) : integer;
var
i, result : integer;
begin
result := n;
for i := 2 to exp do
result := result * n;
pow := result;
end;
Then the main portion of your program is simpler.
program powers;
var
n, i, sum : integer;
function pow(n, exp : integer) : integer;
var
i, result : integer;
begin
result := n;
for i := 2 to exp do
result := result * n;
pow := result;
end;
begin
sum := 0;
write('enter N:');
readln(n);
for i := 0 to n do
sum := sum + pow(i, i);
writeln('result=', sum);
end.
Now that I finally understand what you're asking, please try this:
Program powers;
Var
i, j, n, p, result : integer;
BEGIN
write('enter N:');
readln(n);
Result := 0;
for i := 1 to n do
begin
p := 1;
for j := 1 to i do
p := p * i;
Result := Result + p;
end;
writeln('result=', result);
END.

Does HelpNDoc Pascal Script support structures?

I am trying to create a structure:
MyTopic
TopicID : String;
HelpID : Integer;
I wanted to create an array of these structures so I could sort them.
I have tried using this type / record syntax but it is failing.
Update
I defined this type and procedure:
type
TMyTopicRecord = record
idTopic : String;
idContextHelp : integer;
End;
procedure GetSortedTopicIDs(aTopics : array of String; size : Integer);
var
aMyTopicRecords : array of TMyTopicRecord;
temp : TMyTopicRecord;
iTopic, i, j : Integer;
begin
// Init the array
SetLength(aMyTopicRecords, size);
// Fill the array with the existing topid ids.
// Get the context ids at the same time.
for iTopic := 0 to size - 1 do
aMyTopicRecords[iTopic].idTopic := aTopics[iTopic];
aMyTopicRecords[iTopic].idContextHelp := HndTopics.GetTopicHelpContext(aTopics[iTopic]);
// Sort the array on context id
for i := size-1 DownTo 1 do
for j := 2 to i do
if (aMyTopicRecords[j-1].idContextHelp > aMyTopicRecords[j].idContextHelp) Then
begin
temp := aMyTopicRecords[j-1];
aMyTopicRecords[j-1] := aMyTopicRecords[j];
aMyTopicRecords[j] := temp;
end;
// Rebuild the original array of topic ids
for iTopic := 0 to size - 1 do
aTopics[iTopic] := aMyTopicRecords[iTopic].idTopic;
end;
The procedure gets called in a loop of the parent function (code snipped):
function GetKeywordsAsHtml(): string;
var
aKeywordList: THndKeywordsInfoArray;
aAssociatedTopics: array of string;
nBlocLevel, nDif, nClose, nCurKeywordLevel, nCurKeywordChildrenCnt: Integer;
nCurKeyword, nCurKeywordTopic: Integer;
nCountAssociatedTopics: Integer;
sCurrentKeyword, sKeywordLink, sKeywordRelated: string;
sKeywordJsCaption: string;
begin
Result := '<ul>';
nBlocLevel := 0;
try
aKeywordList := HndKeywords.GetKeywordList(False);
for nCurKeyword := 0 to length(aKeywordList) - 1 do
begin
sCurrentKeyword := aKeywordList[nCurKeyword].id;
nCurKeywordLevel := HndKeywords.GetKeywordLevel(sCurrentKeyword);
nCurKeywordChildrenCnt := HndKeywords.GetKeywordDirectChildrenCount(sCurrentKeyword);
sKeywordLink := '#';
sKeywordRelated := '[]';
aAssociatedTopics := HndTopicsKeywords.GetTopicsAssociatedWithKeyword(sCurrentKeyword);
nCountAssociatedTopics := Length(aAssociatedTopics);
if nCountAssociatedTopics > 0 then
begin
GetSortedTopicIDs(aAssociatedTopics, nCountAssociatedTopics);
// Code snipped
end;
end;
finally
Result := Result + '</ul>';
end;
end;
The script compiled in the HelpNDoc internal editor with no issues. But when I go to actually build my HTML documentation I encounter a problem:
The HelpNDoc API is explained here.
Is there something wrong with my code?
I decided to go about it a different way and used a simpler technique:
procedure GetSortedTopicIDs(var aTopics : array of String; iNumTopics : Integer);
var
iTopic : Integer;
// List of output
aList: TStringList;
begin
// Init list
aList := TStringList.Create;
// Build a new array of "nnn x"
// - nnn is the help context id
// - x is the topid id
// Note: I know that the context ID values are within the range 0 - 200
for iTopic := 0 to iNumTopics - 1 do
// We pad the context id with 0. We could increase the padding width to
// make the script mre useful
aList.Add(Format('%0.3d %s', [
HndTopics.GetTopicHelpContext(aTopics[iTopic]),
aTopics[iTopic]
]));
// Now we sort the new array (which basically sorts it by context id)
aList.Sort;
// Update original array
for iTopic := 0 to iNumTopics - 1 do
// We ignore the "nnn " part of the string to get just the topic id
aTopics[iTopic] := copy(aList[iTopic],5, length(aList[iTopic])-4);
// Tidy up
aList.Free;
end;
This compiles and I get the sorted array of topic IDs at the end of it. So the pop-up help is now listed as I want.

How Do I convert bytes to ASCII chars, using Oracle PL/SQL

I have a problem with conversion this bytes to ASCII chars, need to do similar conversion using Oracle PL/SQL, the original one is in MS SQLserver:
/// </summary>
/// <param name="blob"></param>
/// <returns></returns>
[Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static String VarbinaryToVarchar(SqlBytes blob)
{
if (blob.IsNull) return null;
byte[] buffer = blob.Buffer;
char[] res = new char[buffer.Length * 2];
for (int i = 0; i < buffer.Length; i++)
{
res[i * 2] = (char)((buffer[i] & 0xF) + 65);
res[i * 2 + 1] = (char)(((buffer[i] >> 4) & 0xF) + 65);
}
return new String(res);
}
Thanks in advance guys!
You could explore the use of Oracle built-in UTL_RAW coupled with HEXTORAW, then convert your hex. value to integer and add "65". After that, CHR will give you the ASCII you expect:
declare
p_s_in varchar2(1000):= '0000EB862CB8024892CD419A26BB3AE';
l_s_cmp varchar2(1000):= 'AAAALOGIMCILCAIEJNBEKJGCLIDLOK';
l_s_out varchar2(1000) :='';
p_pad binary_integer:=1;
l_cur1 char;
l_cur2 char;
l_cur_bi1 binary_integer;
l_cur_bi2 binary_integer;
begin
l_cur1 := substr(p_s_in, 1,1);
l_cur2 := substr(p_s_in, 2, 1);
while (length(l_cur1)=1)
loop
l_cur_bi1 := UTL_RAW.cast_to_binary_integer(HEXTORAW(l_cur1))+65;
l_cur_bi2 := UTL_RAW.cast_to_binary_integer(HEXTORAW(l_cur2))+65;
dbms_output.put_line(l_cur2||'->'||chr(l_cur_bi2)||'?>'||substr(l_s_cmp, 1,1));
l_s_cmp := substr(l_s_cmp, 2);
dbms_output.put_line(l_cur1||'->'||chr(l_cur_bi1)||'?>'||substr(l_s_cmp, 1,1));
l_s_out:=l_s_out||chr(l_cur_bi2)||chr(l_cur_bi1);
-- end loop
p_s_in := substr(p_s_in, 3);
l_s_cmp := substr(l_s_cmp, 2);
l_cur1 := substr(p_s_in, 1, 1);
l_cur2 := substr(p_s_in, 2, 1);
end loop;
dbms_output.put_line(l_s_out);
end;
/
I let debugging output, because I'm not completely sure this is what you're looking for. You gave us an output that slightly differs from what I get with your code:
... you or I might be missing something.

how to compare two linear lists in pascal

The task is to create new list which contains 2 linear lists, and if elements of first list equal to elements of second list then we must delete the same element from new list
procedure CreateList(var t1,L1,t2,L2:plist);
var
tmp1, tmp2:plist;
begin
t1 := L1;
t2 := L2;
while t1 <> nil do
begin
write(t1^.Data, ' ');
t1 := t1^.Next;
while t2 <> nil do
begin
write(t2^.data, ' ');
tmp2:=t2;
t2 := t2^.Next;
if(t2 = tmp1^.next) then // here is the problem how to compare 2 elements
begin
tmp1 := t1;
t1 := t1^.Next;
Dispose(tmp1);
end;
end;
end;
Writeln;
readkey;
end;
I advise you to change type of you list for something like:
type
TData = integer;
PList = ^TList;
TList = record
data : TData;
next : PList;
copy : boolean;
end;
After you will use value .copy for checking copys. Here is simple code you need.
I tried to make all code as simple as possible.
procedure deleteCopys(var list:PList);
// make all TList.copy := false (after we will use it)
var
curList : PList;
begin
curList := list;
while (curList<>nil) do
begin
curList^.copy := false;
curList := curList^.next;
End;
End;
procedure createList(var list1, list2, list3:PList);
// we belive that: (list3 is empty) and (there is no copys in list1)
// and (there is no copys in list2)
var
curList1, curList2 : PList;
begin
deleteCopys(list1);
deleteCopys(list2);
deleteCopys(list3);
// make TList.copy := true for equal elements
// from curList1 and curList2
curList1 := list1;
while (curList1 <> nil) do
begin
curList2 := list2;
while (curList2 <> nil) do
begin
if (curList1^.data = curList2^.data) then
begin
curList1^.copy := true;
curList2^.copy := true;
break;
End;
curList2 := curList2^.next;
End;
curList1 := curList1^.next;
End;
// now we can put all elements from list1 and list2
// with state TLilt.copy=false
// and each of them will be different
// (Let's do it :)
curList1 := list1;
while (curList1 <> nil) do
begin
if (curList1^.copy = false) then
begin
//some procedure for new element
putNewElement(list3, curList1^.data);
End;
End;
curList2 := list2;
while (curList2 <> nil) do
begin
if (curList2^.copy = false) then
begin
//some procedure for new element
putNewElement(list3, curList2^.data);
End;
End;
end;
I hope it will help you!