File: AdobeToolsC.mesa - created by JCS. Last edit:
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
JCS 2-Mar-86 14:58:34
RSF   17-Apr-85 13:06:40
Philip James, March 9, 1992 1:12 pm PST
Christian Jacobi, April 7, 1992 5:37 pm PDT
Copyright (C) 1985, 1986 by Xerox Corporation. All rights reserved.
QueryList
DIRECTORY
AdobeCommon USING [AddToOtherQLList, AddToSet, ButtonSeqObject, EnumeratedTypesRec, GetNextAR, GrowSet, Handle, InitialSetStatus, PostMessage, SetStatus, StringArray],
AdobeCommonInternal USING [InstanceDataHandle, InstanceData],
AdobeOps USING [ARNumber, ARSystemHandle, QLHandle, QueryList, QueryListBody, SetOfARs, SetOfARsObject],
AdobeTool,
AccessCH USING [NSNameFromRope],
Buttons USING [ButtonProc],
Convert USING [CardFromRope, RopeFromCard, RopeFromChar],
IO USING [Close, EndOfStream, GetChar, PutChar, PutRope, STREAM],
PFS USING [Error, PathFromRope, StreamOpen],
Rope USING [Concat, Equal, Fetch, Length, ROPE],
XNSAdobeClientOps USING [ReadLastARNumber];
AdobeToolImplC: CEDAR MONITOR
IMPORTS AdobeCommon, AccessCH, Convert, IO, PFS, Rope, XNSAdobeClientOps
EXPORTS AdobeTool = {
globals for queryList
unionPos: CARDINAL = 0;
intsctnPos: CARDINAL = 1;
compPos: CARDINAL = 2;
diffPos: CARDINAL = 3;
xorPos: CARDINAL = 4;
copyToListPos: CARDINAL = 5;
copyToFilePos: CARDINAL =6;
op1Pos: CARDINAL = 7;
op2Pos: CARDINAL = 8;
resultPos: <<PUBLIC>> CARDINAL = 9;--used in QLNameHints in AdobeCommonImplE
nQLParams: CARDINAL = 10;
backStr: Rope.ROPE ¬ NIL;
NilFormProc: FormSW.ClientItemsProcType = {
freeDesc ← TRUE;
items ← FormSW.AllocateItemDescriptor[1];
items[0] ← FormSW.StringItem[invisible: TRUE, string: @backStr]};
CreateQuerylistSW: PUBLIC PROCEDURE[
w: AdobeCommon.Handle, makeCmdSW: BOOLEANTRUE]
RETURNS[initialMsg: Rope.ROPENIL] =
BEGIN
data: AdobeCommon.Handle ← AdobeCommon.GetData[w];
instanceData: AdobeCommonInternal.InstanceDataHandle ← NARROW[data.instanceData];
IF makeCmdSW THEN {
instanceData ← AdobeCommonInternal.AllocateInstanceData[data];
instanceData.cmdSW ← Tool.MakeFormSW[
window: w, formProc: QueryListCmdSW, zone: data.heap]};
instanceData.formSW ← Tool.MakeFormSW[
window: w, formProc: QueryListFormSW, zone: data.heap];
AdobeCommon.DisableAdobeAborts[w];
AdobeCommonInternal.SetWindowName[
w, IF data.knownSystems # NIL AND data.context # NIL AND
data.system # LAST[CARDINAL] THEN
data.knownSystems[data.system] ELSE NIL,
AdobeCommonInternal.queryListHeraldName];
END;
SetUpQueryListTool: PUBLIC PROCEDURE [handle: AdobeCommon.Handle] = {
handle.fieldViewer.buttons ¬ NEW[AdobeCommon.ButtonSeqObject[1]];
handle.fieldViewer.buttons[0] ¬ NEW[AdobeCommon.EnumeratedTypesRec];
handle.fieldViewer.buttons[0].button ¬ handle.makeButton[
x: 3, y: 5, name: "List: ", scrollable: FALSE, parent: handle.fieldViewer.outer, --border: FALSE--
proc: $ListAction, data: handle, cData: handle, paint: TRUE];
handle.editors[4] ¬ handle.newFieldBox[
parent: handle.fieldViewer.outer, x: 3 + handle.getBoxGeometry[handle.fieldViewer.buttons[0].button].w, y: 6, w: 400, h: 800, scrollable: FALSE, border: FALSE];
};
QueryListCmdSW: FormSW.ClientItemsProcType = {
OPEN FormSW;
windowData: AdobeCommon.Handle ← AdobeCommon.GetDataSW[sw];
instanceData: AdobeCommonInternal.InstanceDataHandle ←
windowData.instanceData;
WITH qLToolData: instanceData SELECT FROM
queryList => {
items ← AllocateItemDescriptor[nQLParams, windowData.heap];
freeDesc ← TRUE;
items[unionPos] ← CommandItem[
tag: "Union", place: [0, line0], proc: QLCommandProc--,
--z: windowData.heap--];
items[intsctnPos] ← CommandItem[
tag: "Intersection", place: [72, line0],
proc: QLCommandProc--, z: windowData.heap--];
items[compPos] ← CommandItem[
tag: "Complement", place: [195, line0],
proc: QLCommandProc--, z: windowData.heap--];
items[diffPos] ← CommandItem[
tag: "Difference", place: [306, line0],
proc: QLCommandProc--, z: windowData.heap--];
items[xorPos] ← CommandItem[
tag: "XOR", place: [408, line0],
proc: QLCommandProc--, z: windowData.heap--];
items[copyToListPos] ← CommandItem[
tag: "CopyToQueryList", place: [0, line1],
proc: QLCommandProc--, z: windowData.heap--];
items[copyToFilePos] ← CommandItem[
tag: "CopyToFile", place: [119, line1],
proc: QLCommandProc--, z: windowData.heap--];
items[op1Pos] ← StringItem[
tag: "Operand1", string: @qLToolData.operand1,
place: [0, line2], menuProc: QLNameHintsForQueryList--,
--z: windowData.heap, inHeap: TRUE--];
items[op2Pos] ← StringItem[
tag: "Operand2", string: @qLToolData.operand2,
place: [171,line2], menuProc: QLNameHintsForQueryList--,
--z: windowData.heap, inHeap: TRUE--];
items[resultPos] ← StringItem[
tag: "Result", place: [348,line2],
string: @qLToolData.result, menuProc: QLNameHintsForQueryList--,
--z: windowData.heap, inHeap: TRUE--];
};
ENDCASE => ERROR; --shouldn't happen
};
QLNameHintsForQueryList: PUBLIC Buttons.ButtonProc = {
FormSW.MenuProcType = BEGIN
arSH: AdobeOps.ARSystemHandle;
data: AdobeCommon.Handle ¬ NARROW[clientData]; --AdobeCommon.GetDataSW[sw];
hintsLength, hintsIndex: CARDINAL ¬ 0;
hintSeq: REF AdobeCommon.StringArray;
list: AdobeOps.QLHandle;
CountOtherQLs: PROCEDURE RETURNS [count: CARDINAL ¬ 0] =
BEGIN
list: AdobeOps.QLHandle ¬ arSH.otherQLs;
WHILE list # NIL DO
count ¬ count + 1;
list ¬ list.next;
ENDLOOP;
END;
IF data.context = NIL THEN {
hints ← NIL; RETURN};
arSH ¬ data.systemHandle;
freeHintsProc ← AdobeCommon.FreeHintStrings;
replace ← TRUE;
hintsLength ¬ CountOtherQLs[];
hintsLength ¬ hintsLength + 3;
hintsIndex ¬ 3;
hintSeq ¬ NEW[AdobeCommon.StringArray[hintsLength]];
hintSeq[0] ¬ "SysQL";
hintSeq[1] ¬ "List";
hintSeq[2] ¬ "filename";
list ¬ arSH.otherQLs;
WHILE list # NIL DO
hintSeq[hintsIndex] ¬ list.qL.name;
hintsIndex ¬ hintsIndex + 1;
list ¬ list.next;
ENDLOOP;
hints ← DESCRIPTOR[hintSeq];
};
QueryListFormSW: FormSW.ClientItemsProcType =
BEGIN OPEN FormSW;
windowData: AdobeCommon.Handle ← AdobeCommon.GetDataSW[sw];
instanceData: AdobeCommonInternal.InstanceDataHandle ←
NARROW[windowData.instanceData];
WITH qLToolData: instanceData SELECT FROM
queryList => {
items ← AllocateItemDescriptor[1, windowData.heap];
freeDesc ← TRUE;
items[0] ← StringItem[
tag: "List", string: @qLToolData.list,
place: [0, line0]--, z: windowData.heap, inHeap: TRUE--]};
ENDCASE => ERROR; --shouldn't happen
END;
QLCommandProc: PUBLIC Buttons.ButtonProc = {
FormSW.ProcType = {
windowData: AdobeCommon.Handle ← NARROW[clientData]; --AdobeCommon.GetDataSW[sw];
instanceData: AdobeCommonInternal.InstanceDataHandle ←
NARROW[windowData.instanceData];
MsgSW.Clear[windowData.msgSW];
IF windowData.system = LAST[CARDINAL] --OR windowData.context = NIL --OR windowData.knownSystems = NIL OR windowData.knownSystems.next = 0 THEN {
AdobeCommon.PostMessage[windowData, TRUE, "No available systems"];
RETURN};
IF windowData.isBusy THEN
AdobeCommon.PostMessage[windowData, TRUE,
"Adobe system is Busy. Please try again later. "]
ELSE {
windowData.isBusy ← TRUE;
IF instanceData.background AND ~TajoMisc.toolDriverRunning THEN
Process.Detach[
windowData.processID ← FORK AdobeCommon.CatchErrors[
sw, item, index, windowData, ChooseQLCmd]]
ELSE {
windowData.processID ← Process.GetCurrent[];
AdobeCommon.CatchErrors[
--sw, item, index, --windowData, ChooseQLCmd]}--};
};
ChooseQLCmd: PUBLIC PROCEDURE [windowData: AdobeCommon.Handle, index: CARD] = {
FormSW.ProcType = {
windowData: AdobeCommon.Handle ← AdobeCommon.GetDataSW[sw];
{
ENABLE UNWIND => windowData.isBusy ¬ FALSE;
windowData.isBusy ¬ TRUE;
IF windowData.context # NIL THEN {
SELECT index FROM
unionPos => ORSets[windowData];
intsctnPos => ANDSets[windowData];
copyToListPos => CopySet[windowData, FALSE];
copyToFilePos => CopySet[windowData, TRUE];
compPos => ComplementSet[windowData];
diffPos => DifferenceOfSets[windowData];
xorPos => XORSets[windowData];
ENDCASE => ERROR;
windowData.isBusy ¬ FALSE;
windowData.processID ← NIL;
AdobeCommon.PostMessage[windowData, TRUE, "Done. "]
}
ELSE AdobeCommon.PostMessage[windowData, TRUE, "Adobe is not set to an Adobe system. "];
};
};
NotDoneYet: PROCEDURE [windowData: AdobeCommon.Handle] =
BEGIN
AdobeCommon.PostMessage[windowData, TRUE, "Not Done Yet. "];
END;
ORSets: PROCEDURE[data: AdobeCommon.Handle] =
BEGIN
set1, set2, resultSet: AdobeOps.SetOfARs ¬ NIL;
AdobeCommon.PostMessage[data, FALSE, "Taking Union ... "];
set1 ¬ GetSetOne[data];
set2 ¬ GetSetTwo[data];
cannot use AdobeCommon.OrSets because it will free set1 and set2
resultSet ← AdobeCommon.OrSets[set1, set2];
resultSet ¬ OrSetsImplB[set1, set2];
StoreQLinQueryList[data, resultSet];
END; --of ORSets
ANDSets: PROCEDURE[data:AdobeCommon.Handle] =
BEGIN
set1, set2, resultSet: AdobeOps.SetOfARs ¬ NIL;
AdobeCommon.PostMessage[data, FALSE, "Taking Intersection ... "];
set1 ¬ GetSetOne[data];
set2 ¬ GetSetTwo[data];
cannnot use AdobeCommon.AndSets because it will free set1 and set2
resultSet ← AdobeCommon.AndSets[set1, set2];
resultSet ¬ AndSetsImplB[set1, set2];
StoreQLinQueryList[data, resultSet];
END; --of ANDSets
CopySet: PROCEDURE [data: AdobeCommon.Handle, toFile: BOOLEAN] = {
copies a querylist into a file or to list
the querylist is gotten from operand1
if the result field is not equal to "list" then, the filename is gotten from
the result field
sH: IO.STREAM;
sH: MStream.Handle;
mfRD: MStream.ReleaseData ← [NIL, NIL];
set: AdobeOps.SetOfARs ¬ NIL;
instanceData:AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData];
formItem: FormSW.ItemHandle;
code
AdobeCommon.PostMessage[data, FALSE, "Copying ... "];
set ¬ GetSetOne[data];
WITH instanceData SELECT FROM
queryListData: REF AdobeCommonInternal.InstanceData.queryList => {
queryListData.result ¬ data.getContents[data.editors[3]];
IF Rope.Equal[queryListData.result, "list", FALSE] THEN {
formItem ← FormSW.FindItem[instanceData.formSW, 0];
formItem.flags.invisible ← TRUE;
StoreQLinFileOrList[set, NIL, data];
data.setContents[data.editors[4], queryListData.list];
AdobeCommon.PostMessage[data, TRUE, "copying to List. "];
formItem.flags.invisible ← FALSE;
FormSW.DisplayItem[queryListData.formSW, 0]
}
ELSE IF Rope.Equal[queryListData.result, "sysql", FALSE] THEN {
AdobeCommon.PostMessage[data, TRUE, "copying to SysQL. "];
IF data.systemHandle.sysQL = NIL THEN
data.systemHandle.sysQL ¬ NEW[AdobeOps.QueryListBody];
data.systemHandle.sysQL.list ¬ set}
ELSE {
IF ~toFile THEN StoreQLinQueryList[data, set]
ELSE {
sH ¬ PFS.StreamOpen[PFS.PathFromRope[queryListData.result], write !
PFS.Error => {
AdobeCommon.PostMessage[data, FALSE, " ERROR--"];
IF queryListData.result =NIL OR queryListData.result.Length = 0 THEN
AdobeCommon.PostMessage[data, FALSE, "no file specified in result field"]
ELSE {
AdobeCommon.PostMessage[data, FALSE, queryListData.result];   AdobeCommon.PostMessage[data, FALSE,
" in result field"]};
AdobeCommon.PostMessage[data, TRUE, " cannot be obtained."];
ERROR ABORTED}];
sH ← MStream.WriteOnly[queryListData.result, mfRD, text !
MStream.Error => {
AdobeCommon.PostMessage[data, FALSE, " ERROR--"];
IF queryListData.result =NIL OR queryListData.result.Length = 0 THEN
AdobeCommon.PostMessage[data, FALSE, "no file specified in result field"]
ELSE {
AdobeCommon.PostMessage[data, FALSE, queryListData.result];   AdobeCommon.PostMessage[data, FALSE,
" in result field"]};
AdobeCommon.PostMessage[data, TRUE, " cannot be obtained."];
ERROR ABORTED}];
StoreQLinFileOrList[set, sH, data];
sH ¬ CleanUpStream[sH]}}};
ENDCASE => ERROR; --shouldn't happen
}; --of CopySet
ComplementSet: PROCEDURE [data: AdobeCommon.Handle] =
BEGIN
setIndex, tempIndex: CARDINAL ¬ 0;
ARNumber, lastAR: AdobeOps.ARNumber ¬ 0;
set, tempSet, resultSet: AdobeOps.SetOfARs ¬ NIL;
system: Rope.ROPE ¬ data.systemHandle.name;
AdobeServer.ReadLastARNumber returns the total number of AR in the given
system
AdobeCommon.PostMessage[data, FALSE, "Complementing sets ..."];
lastAR ¬ XNSAdobeClientOps.ReadLastARNumber[data.systemHandle.service, AccessCH.NSNameFromRope[system].local];
set ¬ GetSetOne[data];
IF set = NIL THEN {
tempSet ¬ NEW[AdobeOps.SetOfARsObject[1]];
tempSet[0] ¬ [1, lastAR];
StoreQLinQueryList[data, tempSet];
RETURN}
ELSE {
tempSet ¬ NEW[AdobeOps.SetOfARsObject[set.len + 1]];
initialize tempSet
FOR i: CARDINAL IN [0..tempSet.len) DO
tempSet[i] ¬ [0,0];
ENDLOOP};
IF set[setIndex].startValue # 1 THEN {
tempSet[tempIndex].startValue ¬ 1;
IF set[setIndex].startValue <= lastAR THEN
tempSet[tempIndex].runLength ¬ set[setIndex].startValue - 1
ELSE tempSet[tempIndex].runLength ¬ lastAR;
tempIndex ¬ tempIndex + 1};
WHILE setIndex < set.len DO
ARNumber ¬ set[setIndex].startValue + set[setIndex].runLength;
IF ARNumber >= lastAR + 1 THEN EXIT;
tempSet[tempIndex].startValue ¬ ARNumber;
setIndex ¬ setIndex + 1;
IF setIndex < set.len THEN
IF set[setIndex].startValue = lastAR THEN
tempSet[tempIndex].runLength ¬ lastAR - tempSet[tempIndex].startValue
ELSE IF set[setIndex].startValue > lastAR THEN
tempSet[tempIndex].runLength ¬ lastAR - tempSet[tempIndex].startValue + 1
ELSE tempSet[tempIndex].runLength ¬ set[setIndex].startValue - ARNumber
ELSE tempSet[tempIndex].runLength ¬ lastAR - ARNumber + 1;
tempIndex ¬ tempIndex + 1;
ENDLOOP;
prune tempSet
resultSet ¬ PruneQL[tempSet, tempIndex - 1];
StoreQLinQueryList[data, resultSet];
END;--of ComplementSet
DifferenceOfSets: PROCEDURE [data:AdobeCommon.Handle] =
BEGIN
assume that ARs given are in numeric order
ar1, ar2: AdobeOps.ARNumber ¬ 0;
set1, set2: AdobeOps.SetOfARs ¬ NIL;
set1Status, set2Status: AdobeCommon.SetStatus ¬ AdobeCommon.InitialSetStatus;
resultState: CARDINAL ¬ 0;
resultSet, tempSet: AdobeOps.SetOfARs ¬ NIL;
AdobeCommon.PostMessage[data, FALSE, "Taking difference ... "];
set1 ¬ GetSetOne[data];
set2 ¬ GetSetTwo[data];
IF set1 = NIL THEN {StoreQLinQueryList[data, NIL]; RETURN};
IF set2 = NIL THEN {StoreQLinQueryList[data, set1]; RETURN};
tempSet ¬ NEW[AdobeOps.SetOfARsObject[set1.len]];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status];
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
initialize temp
FOR i: CARDINAL IN [0..tempSet.len) DO
tempSet[i] ¬ [0,0];
ENDLOOP;
For the difference of two sets, set1-set2, if set1 is exhausted first,
we are done or if set2 is exhausted first, append what remains on
set1 to the resultset.
WHILE set1Status.setIndex < set1.len AND set2Status.setIndex < set2.len DO
SELECT TRUE FROM
ar1 = ar2 => {
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]};
ar1 > ar2 =>
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
ar1 < ar2 => {
resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]};
ENDCASE;
ENDLOOP;
if set2 is exhausted first then append what remains on set1 to resultset.
WHILE set1Status.setIndex < set1.len DO
resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status];
ENDLOOP;
prune tempSet
resultSet ¬ PruneQL[tempSet, resultState];
StoreQLinQueryList[data, resultSet];
END; -- of DifferenceOfSets
XORSets: PROCEDURE[data: AdobeCommon.Handle] =
BEGIN
assume that ARs given are in numeric order
ar1, ar2: AdobeOps.ARNumber ¬ 0;
set1,set2: AdobeOps.SetOfARs ¬ NIL;
set1Status, set2Status: AdobeCommon.SetStatus ¬ AdobeCommon.InitialSetStatus;
resultState: CARDINAL ¬ 0;
resultSet, tempSet: AdobeOps.SetOfARs ¬ NIL;
AdobeCommon.PostMessage[data, FALSE, "XORing sets ..."];
set1 ¬ GetSetOne[data];
set2 ¬ GetSetTwo[data];
IF set1 = NIL THEN {StoreQLinQueryList[data, set2]; RETURN};
IF set2 = NIL THEN {StoreQLinQueryList[data, set1]; RETURN};
tempSet ¬ NEW[AdobeOps.SetOfARsObject[set1.len + set2.len]];
initialize tempSet
FOR i: CARDINAL IN [0..tempSet.len) DO
tempSet[i] ¬ [0,0];
ENDLOOP;
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status];
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
WHILE set1Status.setIndex < set1.len AND set2Status.setIndex < set2.len DO
SELECT TRUE FROM
ar1 = ar2 => {
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]};
ar1 > ar2 => {
resultState ¬ AdobeCommon.AddToSet[ar2, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status]};
ar1 < ar2 => {
resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status]};
ENDCASE;
ENDLOOP;
WHILE set1Status.setIndex < set1.len DO
resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status];
ENDLOOP;
WHILE set2Status.setIndex < set2.len DO
resultState ¬ AdobeCommon.AddToSet[ar2, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
ENDLOOP;
prune tempSet
resultSet ¬ PruneQL[tempSet, resultState];
StoreQLinQueryList[data, resultSet];
END; --of XORSets
GetSetOne: PROCEDURE[data:AdobeCommon.Handle] RETURNS[set1: AdobeOps.SetOfARs ¬ NIL] =
BEGIN
qlH: AdobeOps.QLHandle ¬ NIL;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData];
WITH instanceData SELECT FROM
queryListData: REF AdobeCommonInternal.InstanceData.queryList => {
queryListData.operand1 ¬ data.getContents[data.editors[1]];
SELECT TRUE FROM
queryListData.operand1 = NIL OR queryListData.operand1.Length = 0 => {
AdobeCommon.PostMessage[data, TRUE, "sysQL will be used for operand1. "];
IF data.systemHandle.sysQL = NIL THEN RETURN[NIL]
ELSE RETURN[data.systemHandle.sysQL.list]};
Rope.Equal[queryListData.operand1, "list", FALSE] => {
set1 ¬ GetList[data];
RETURN[set1]};
Rope.Equal[queryListData.operand1, "sysQL", FALSE] => {
IF data.systemHandle.sysQL = NIL THEN RETURN[NIL]
ELSE RETURN[data.systemHandle.sysQL.list]};
ENDCASE => {
qlH ¬ data.systemHandle.otherQLs;
WHILE qlH # NIL DO
IF Rope.Equal[queryListData.operand1, qlH.qL.name, FALSE] THEN
RETURN[qlH.qL.list];
qlH ¬ qlH.next;
ENDLOOP;
if this code is executed then operand1 is not in otherqls.
before returning sysQL, check if operand1 is a filename
RETURN[RetrieveQL[queryListData.operand1, data]]};
};
ENDCASE; --shouldn't happen;
END; --of GetSetOne
GetSetTwo: PROCEDURE [data: AdobeCommon.Handle] RETURNS[set2: AdobeOps.SetOfARs] =
BEGIN
qlH:AdobeOps.QLHandle ¬ NIL;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData];
WITH instanceData SELECT FROM
queryListData: REF AdobeCommonInternal.InstanceData.queryList => {
queryListData.operand2 ¬ data.getContents[data.editors[2]];
SELECT TRUE FROM
queryListData.operand2 = NIL OR queryListData.operand2.Length = 0 => {
AdobeCommon.PostMessage[
data, TRUE, "sysQL will be used for operand2. "];
IF data.systemHandle.sysQL = NIL THEN RETURN[NIL]
ELSE RETURN[data.systemHandle.sysQL.list]};
Rope.Equal[queryListData.operand2, "list", FALSE] => {
set2 ¬ GetList[data];
RETURN[set2]};
Rope.Equal[queryListData.operand2, "sysQL", FALSE] => {
<<IF data.systemHandle.sysQL = NIL THEN {
data.systemHandle.sysQL ¬ NEW[AdobeOps.QueryListBody];
data.systemHandle.sysQL.list ¬ NIL}>>
IF data.systemHandle.sysQL = NIL THEN RETURN[NIL]
ELSE RETURN[data.systemHandle.sysQL.list]};
ENDCASE => {
qlH ¬ data.systemHandle.otherQLs;
WHILE qlH # NIL DO
IF Rope.Equal[queryListData.operand2, qlH.qL.name, FALSE] THEN
RETURN[qlH.qL.list];
qlH ¬ qlH.next;
ENDLOOP;
if this code is executed then operand2 is not in otherqls.
before returning sysQL, check if operand2 is a filename
RETURN[RetrieveQL[queryListData.operand2, data]]};
};
ENDCASE; --shouldn't happen;
END; --of GetSetTwo
GetList: PROCEDURE [data:AdobeCommon.Handle] RETURNS [resultSet: AdobeOps.SetOfARs ¬ NIL] =
BEGIN
qlH:AdobeOps.QLHandle ¬ NIL;
setIndex: CARDINAL ¬ 0;
listIndex: INTEGER ¬ 0;
arNumberString: Rope.ROPE ¬ NIL;
arNumber, prevarNumber: AdobeOps.ARNumber ¬ 0;
set: AdobeOps.SetOfARs ¬ NIL;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData];
BEGIN ENABLE {
UNWIND => {
IF arNumberString # NIL THEN arNumberString ¬ NIL;
IF set # NIL THEN set ¬ NIL } };
AdobeOps.z.FREE[@set]}};
GetAR: PROCEDURE[list: Rope.ROPE] =
BEGIN
arNumber ¬ 0;
WHILE listIndex < list.Length AND list.Fetch[listIndex] = ' DO
listIndex ¬ listIndex + 1;
ENDLOOP;
IF listIndex < list.Length AND list.Fetch[listIndex] NOT IN ['0..'9] AND list.Fetch[listIndex] # '- THEN {
AdobeCommon.PostMessage[data, TRUE, "Invalid character entered in List."];
ERROR ABORTED};
WHILE listIndex < list.Length AND list.Fetch[listIndex] IN ['0..'9] DO
arNumberString ¬ arNumberString.Concat[Convert.RopeFromChar[list.Fetch[listIndex], FALSE]];
String.AppendChar[arNumberString, list.Fetch[listIndex]];
listIndex ¬ listIndex + 1;
ENDLOOP;
IF listIndex < list.Length AND list.Fetch[listIndex] # ' AND list.Fetch[listIndex] # '- THEN {
AdobeCommon.PostMessage[data, TRUE, "Invalid character entered in List."];
ERROR ABORTED};
IF arNumberString.Length #0 THEN {
arNumber ¬ Convert.CardFromRope[arNumberString];
IF arNumber = 0 THEN {
AdobeCommon.PostMessage[data, TRUE, "AR number 0 is invalid"];
ERROR ABORTED}};
arNumberString ¬ ClearString[arNumberString];
WHILE listIndex < list.Length AND list.Fetch[listIndex] = ' DO
listIndex ¬ listIndex + 1;
ENDLOOP;
IF listIndex < list.Length AND list.Fetch[listIndex] NOT IN ['0..'9] AND list.Fetch[listIndex] # '- THEN {
AdobeCommon.PostMessage[data, TRUE, "Invalid character entered in List."];
ERROR ABORTED};
END;--of GetAR
WITH instanceData SELECT FROM
queryListData: REF AdobeCommonInternal.InstanceData.queryList => {
queryListData.list ¬ data.getContents[data.editors[4]];
IF queryListData.list = NIL OR queryListData.list.Length = 0 THEN RETURN[NIL];
arNumberString ← String.MakeString[data.heap, 16];
set ¬ NEW[AdobeOps.SetOfARsObject[10]];
initialize temp
FOR i: CARDINAL IN [0..set.len) DO
set[i] ¬ [0,0];
ENDLOOP;
WHILE listIndex < queryListData.list.Length DO
GetAR[queryListData.list];
SELECT TRUE FROM
prevarNumber = 0 AND arNumber = 0 => AdobeCommon.PostMessage[data, TRUE, "List is empty or invalid list format. An empty query list has been created"];
prevarNumber > arNumber AND arNumber # 0 => {  AdobeCommon.PostMessage[data, TRUE, "The numbers entered in list should be in ascending order."];
ERROR ABORTED};
prevarNumber = arNumber => {
AdobeCommon.PostMessage[data, TRUE, "Duplicate numbers."];
ERROR ABORTED};
ENDCASE;
prevarNumber ¬ arNumber;
IF set[setIndex].startValue + set[setIndex].runLength = arNumber THEN
set[setIndex].runLength ¬ set[setIndex].runLength + 1
ELSE {
IF set[setIndex].startValue # 0 THEN {
setIndex ¬ setIndex + 1;
IF setIndex = set.len THEN AdobeCommon.GrowSet[NEW[AdobeOps.SetOfARs ¬ set]]};
set[setIndex].startValue ¬ arNumber;
set[setIndex].runLength ¬ 1};
IF listIndex < queryListData.list.Length AND queryListData.list.Fetch[listIndex] = '- THEN {
listIndex ¬ listIndex + 1;
GetAR[queryListData.list];
IF prevarNumber > arNumber AND arNumber # 0 THEN {  AdobeCommon.PostMessage[data, TRUE, "The numbers entered in list should be in ascending order."];
ERROR ABORTED};
set[setIndex].runLength ¬ arNumber - set[setIndex].startValue + 1};
ENDLOOP};
ENDCASE;
resultSet ¬ PruneQL[set, setIndex];
END; --enable
END;--of GetList
OrSetsImplB: PROCEDURE [set1, set2: AdobeOps.SetOfARs]
RETURNS [resultSet: AdobeOps.SetOfARs] =
BEGIN
taken from AdobeToolsB, I thought it would be faster to do this rather that to allocate and deallocate two sets
assume that ARs given are in numeric order
ar1, ar2: AdobeOps.ARNumber;
set1Status, set2Status: AdobeCommon.SetStatus ¬ [0, 0];
resultState: CARDINAL ¬ 0;
tempSet: AdobeOps.SetOfARs;
IF set1 = NIL THEN RETURN[set2];
IF set2 = NIL THEN RETURN[set1];
tempSet ¬ NEW[
AdobeOps .SetOfARsObject[set1.len + set2.len]];
ar1 ¬ set1[0].startValue;
ar2 ¬ set2[0].startValue;
initialize temp
FOR i: CARDINAL IN [0..tempSet.len) DO
tempSet[i] ¬ [0, 0]; ENDLOOP;
For OR, when one set is exhausted, we've got to append what
remains of the unexhausted set to the result.
WHILE set1Status.setIndex < set1.len
AND set2Status.setIndex < set2.len DO
SELECT TRUE FROM
ar1 = ar2 => { --add only once
resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[
set1, set1Status]};
ar1 > ar2 => {
resultState ¬ AdobeCommon.AddToSet[ar2, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[
set2, set2Status]};
ar1 < ar2 => {
resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[
set1, set1Status]};
ENDCASE;
ENDLOOP;
IF set1Status.setIndex < set1.len THEN --add rest of set1
WHILE set1Status.setIndex < set1.len DO
resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status];
ENDLOOP
ELSE --add rest of set2
WHILE set2Status.setIndex < set2.len DO
resultState ¬ AdobeCommon.AddToSet[ar2, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
ENDLOOP;
IF resultState + 1 = (set1.len + set2.len) THEN {
AdobeOps.z.FREE[@set1]; we don't want to free this
AdobeOps.z.FREE[@set2]; we don't want to free this
RETURN[tempSet]}
ELSE {
resultSet ¬ NEW[
AdobeOps .SetOfARsObject[resultState + 1]];
FOR i: CARDINAL IN [0..resultSet.len) DO
resultSet[i] ¬ tempSet[i]; ENDLOOP;
AdobeOps.z.FREE[@tempSet]
};
AdobeOps.z.FREE[@set1]; we don't want to free this
AdobeOps.z.FREE[@set2]; we don't want to free this
END;
AndSetsImplB: PROCEDURE [set1, set2: AdobeOps.SetOfARs]
RETURNS [resultSet: AdobeOps.SetOfARs] =
BEGIN
taken from AdobeToolsB, thought it would be faster to do this rather than allocating and deallocating space for the two sets
next time we change AdobeCommon interface add boolean parameter to see if set should be freed
assume that ARs given are in numeric order
ar1, ar2: AdobeOps.ARNumber;
set1Status, set2Status: AdobeCommon.SetStatus ¬
AdobeCommon.InitialSetStatus;
resultState: CARDINAL ¬ 0;
tempSet: AdobeOps.SetOfARs;
IF set1 = NIL THEN {
IF set2 # NIL THEN set2 ¬ NIL;
AdobeOps.z.FREE[@set2];
RETURN[NIL]}
ELSE IF set2 = NIL THEN {
set1 ¬ NIL;
AdobeOps.z.FREE[@set1];
RETURN[NIL]};
tempSet ¬ NEW[
AdobeOps .SetOfARsObject[MAX[set1.len, set2.len]]];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status];
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
initialize temp
FOR i: CARDINAL IN [0..tempSet.len) DO
tempSet[i] ¬ [0, 0]; ENDLOOP;
For AND, when one set is exhausted, we've got all that are
common to both so can just exit knowing we're done
WHILE set1Status.setIndex < set1.len
AND set2Status.setIndex < set2.len DO
SELECT TRUE FROM
ar1 = ar2 => {
resultState ¬ AdobeCommon.AddToSet[ar1, NEW[AdobeOps.SetOfARs ¬ tempSet], resultState];
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[
set1, set1Status]};
ar1 > ar2 =>
[ar2, set2Status] ¬ AdobeCommon.GetNextAR[set2, set2Status];
ar1 < ar2 =>
[ar1, set1Status] ¬ AdobeCommon.GetNextAR[set1, set1Status];
ENDCASE;
ENDLOOP;
IF resultState = 0 AND tempSet[0].startValue = 0 THEN { --empty set
AdobeOps.z.FREE[@tempSet];
AdobeOps.z.FREE[@set1]; we don't want to free this
AdobeOps.z.FREE[@set2]; we don't want to free this
RETURN[NIL]};
prune to just fit
IF resultState + 1 = MAX[set1.len, set2.len] THEN {
AdobeOps.z.FREE[@set1]; we don't want to free this
AdobeOps.z.FREE[@set2]; we don't want to free this
RETURN[tempSet]}
ELSE {
resultSet ¬ NEW[
AdobeOps .SetOfARsObject[resultState + 1]];
FOR i: CARDINAL IN [0..resultSet.len) DO
resultSet[i] ¬ tempSet[i]; ENDLOOP;
AdobeOps.z.FREE[@tempSet]
};
AdobeOps.z.FREE[@set1]; we don't want to free this
AdobeOps.z.FREE[@set2]; we don't want to free this
END;
RetrieveQL: PROCEDURE[fileName: Rope.ROPE, data:AdobeCommon.Handle] RETURNS [resultSet: AdobeOps.SetOfARs ¬ NIL] =
reads a file containing ar numbers
BEGIN
variables
fH: IO.STREAM ¬ NIL;
fH: MStream.Handle ← NIL;
mfRD: MStream.ReleaseData ← [NIL, NIL];
char: CHARACTER ¬ ' ;
prevARNumber, arNumber: AdobeOps.ARNumber ¬ 0;
arNumberString: Rope.ROPE ¬ NIL;
tempSet: AdobeOps.SetOfARs ¬ NIL;
tempIndex: CARDINAL ¬ 0;
endOfFile: BOOLEAN ¬ FALSE;
BEGIN ENABLE {
UNWIND => {
IF fH # NIL THEN IO.Close[fH];
Stream.Delete[fH];
IF arNumberString # NIL THEN arNumberString ¬ NIL;
IF tempSet # NIL THEN tempSet ¬ NIL}};
AdobeOps.z.FREE[@tempSet]}};
GetNextARNumber: PROCEDURE =
BEGIN
WHILE char = ' DO
char ¬ IO.GetChar[fH !IO.EndOfStream => GOTO EOF];
ENDLOOP;
WHILE char IN ['0..'9] AND NOT endOfFile DO
arNumberString ¬ arNumberString.Concat[Convert.RopeFromChar[char, FALSE]];
String.AppendChar[arNumberString, char];
char ¬ IO.GetChar[fH !IO.EndOfStream => GOTO EOF];
ENDLOOP;
WHILE char = ' DO
char ¬ IO.GetChar[fH !IO.EndOfStream => GOTO EOF];
ENDLOOP;
IF char NOT IN ['0..'9] AND char # '- THEN {
AdobeCommon.PostMessage[data, TRUE, "Invalid character in file! ."];
ERROR ABORTED};
prevARNumber ¬ arNumber;
IF arNumberString.Length = 0 THEN {
AdobeCommon.PostMessage[data, TRUE, "Invalid syntax! ."];
ERROR ABORTED};
arNumber ¬ Convert.CardFromRope[arNumberString];
arNumberString ¬ ClearString[arNumberString];
IF arNumber <= prevARNumber THEN {
AdobeCommon.PostMessage[data, TRUE, "AR numbers must be in ascending order! ."];
ERROR ABORTED}
EXITS
EOF => {
IF arNumberString.Length # 0 THEN {
prevARNumber ¬ arNumber;
arNumber ¬ Convert.CardFromRope[arNumberString];
IF arNumber <= prevARNumber THEN {
AdobeCommon.PostMessage[
data, TRUE, "AR numbers must be in ascending order! ."];
ERROR ABORTED};
arNumberString ¬ ClearString[arNumberString]};
endOfFile ¬ TRUE;}
END; --of GetNextARNumber
code
fH ¬ PFS.StreamOpen[PFS.PathFromRope[fileName] ! PFS.Error =>
{AdobeCommon.PostMessage[data, FALSE, fileName];
AdobeCommon.PostMessage[data, TRUE, " does not exist as a querylist or file."];
ERROR ABORTED}];
fH ← MStream.ReadOnly[fileName, mfRD !MStream.Error =>
{AdobeCommon.PostMessage[data, FALSE, fileName];
AdobeCommon.PostMessage[data, TRUE, " does not exist as a querylist or file."];
ERROR ABORTED}];
arNumberString ← String.MakeString[data.heap, 16];
tempSet ¬ NEW[AdobeOps.SetOfARsObject[100]];
initialize temp
FOR i: CARDINAL IN [0..tempSet.len) DO
tempSet[i] ¬ [0,0];
ENDLOOP;
GetNextARNumber[];
tempSet[0].startValue ¬ arNumber;
IF endOfFile OR char IN ['0..'9] THEN
tempSet[0].runLength ¬ 1
ELSE IF NOT endOfFile AND char = '- THEN {
char ¬ IO.GetChar[fH !IO.EndOfStream => {
AdobeCommon.PostMessage[data, TRUE, "Invalid Syntax! ."];
ERROR ABORTED}];
GetNextARNumber[];
tempSet[0].runLength ¬ arNumber - tempSet[0].startValue + 1};
WHILE NOT endOfFile DO
GetNextARNumber[];
IF arNumber # tempSet[tempIndex].startValue + tempSet[tempIndex].runLength THEN{
tempIndex ¬ tempIndex + 1;
IF tempIndex = tempSet.len THEN AdobeCommon.GrowSet[NEW[AdobeOps.SetOfARs ¬ tempSet]];
tempSet[tempIndex].startValue ¬ arNumber;
IF endOfFile OR char IN ['0..'9] THEN
tempSet[tempIndex].runLength ¬ 1
ELSE IF NOT endOfFile AND char = '- THEN {
char ¬ IO.GetChar[fH !IO.EndOfStream => {
AdobeCommon.PostMessage[data, TRUE, "Invalid Syntax! ."];
ERROR ABORTED}];
GetNextARNumber[];
tempSet[tempIndex].runLength ¬
arNumber - tempSet[tempIndex].startValue + 1}}
ELSE {
IF endOfFile OR char IN ['0..'9] THEN
tempSet[tempIndex].runLength ¬ tempSet[tempIndex].runLength + 1
ELSE IF NOT endOfFile AND char = '- THEN {
char ¬ IO.GetChar[fH !IO.EndOfStream => {
AdobeCommon.PostMessage[data, TRUE, "Invalid Syntax! ."];
ERROR ABORTED}];
GetNextARNumber[];
tempSet[tempIndex].runLength ¬
arNumber - tempSet[tempIndex].startValue + 1;}}
ENDLOOP;
fH ¬ CleanUpStream[fH];
arNumberString ¬ NIL;
String.FreeString[data.heap, arNumberString];
prune tempSet if necessary
resultSet ¬ PruneQL[tempSet, tempIndex]
END;
END; --of RetrieveQL
StoreQLinQueryList: PROCEDURE[data: AdobeCommon.Handle, set: AdobeOps.SetOfARs] = {
found: BOOLEAN ¬ FALSE;
qlH: AdobeOps.QLHandle ¬ NIL;
ql: AdobeOps.QueryList ¬ NIL;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData];
formItem: FormSW.ItemHandle;
WITH instanceData SELECT FROM
queryListData: REF AdobeCommonInternal.InstanceData.queryList => {
queryListData.result ¬ data.getContents[data.editors[3]];
IF queryListData.result = NIL OR queryListData.result.Length = 0 THEN
AdobeCommon.PostMessage[
data, TRUE, "ERROR--result field not specified."]
ELSE IF Rope.Equal[queryListData.result, "SysQL", FALSE] THEN {
IF data.systemHandle.sysQL = NIL THEN
data.systemHandle.sysQL ¬ NEW[AdobeOps.QueryListBody];
data.systemHandle.sysQL.list ¬ set}
ELSE IF Rope.Equal[queryListData.result, "List", FALSE] THEN {
formItem ← FormSW.FindItem[instanceData.formSW, 0];
formItem.flags.invisible ← TRUE;
StoreQLinFileOrList[set, NIL, data];
formItem.flags.invisible ← FALSE;
FormSW.DisplayItem[queryListData.formSW, 0]
}
ELSE {
qlH ¬ data.systemHandle.otherQLs;
WHILE qlH # NIL AND found = FALSE DO
IF Rope.Equal[queryListData.result, qlH.qL.name, FALSE] THEN
found ¬ TRUE
ELSE qlH ¬ qlH.next;
ENDLOOP;
IF found THEN qlH.qL.list ¬ set
ELSE {
ql ¬ NEW[AdobeOps.QueryListBody];
ql­.name ¬ queryListData.result;
ql­.list ¬ set;
AdobeCommon.AddToOtherQLList[data.systemHandle, ql]}}};
ENDCASE; --shoud not happen
};--of StoreQLinQueryList
StoreQLinFileOrList: PROCEDURE[set: AdobeOps.SetOfARs, fH: IO.STREAM, data: AdobeCommon.Handle] =
BEGIN
beginValue, runValue, endValue: AdobeOps.ARNumber ¬ 0;
stringValue: Rope.ROPE ¬NIL;
hyphen: CHARACTER ¬ '-;
space: CHARACTER ¬ ' ;
copyToList: BOOLEAN ¬ FALSE;
instanceData: AdobeCommonInternal.InstanceDataHandle ¬ NARROW[data.instanceData];
WITH instanceData SELECT FROM
queryListData: REF AdobeCommonInternal.InstanceData.queryList => {
IF fH = NIL THEN {
copyToList ¬ TRUE;
IF queryListData.list # NIL THEN
queryListData.list ¬ NIL;
queryListData.list ← String.MakeString[data.heap,50];
queryListData.list.Length ← 0
};
IF set # NIL THEN
BEGIN
stringValue ← String.MakeString[data.heap,16];
FOR index:CARDINAL IN [0..set.len) DO
beginValue ¬ set[index].startValue;
stringValue ¬ ClearString[stringValue];
stringValue ¬ stringValue.Concat[Convert.RopeFromCard[beginValue, 10, FALSE]];
String.AppendLongNumber[stringValue, beginValue];
IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[stringValue]
ELSE IO.PutRope[fH, stringValue];
runValue ¬ set[index].runLength;
IF runValue = 1 AND index # set.len - 1 THEN
IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[Convert.RopeFromChar[space, FALSE]]
String.AppendChar[queryListData.list, space]
ELSE IO.PutChar[fH, space]
ELSE IF runValue # 1 THEN {
IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[Convert.RopeFromChar[hyphen, FALSE]]
String.AppendChar[queryListData.list, hyphen]
ELSE IO.PutChar[fH, hyphen];
endValue ¬ beginValue + runValue -1;
stringValue ¬ ClearString[stringValue];
stringValue ¬ stringValue.Concat[Convert.RopeFromCard[endValue, 10, FALSE]];
String.AppendLongNumber[stringValue, endValue];
IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[stringValue]
ELSE IO.PutRope[fH, stringValue];
IF index # set.len - 1 THEN
IF copyToList THEN queryListData.list ¬ queryListData.list.Concat[Convert.RopeFromChar[space, FALSE]]
String.AppendChar[queryListData.list, space]
ELSE IO.PutChar[fH,space]};
ENDLOOP;
stringValue ¬ NIL;
String.FreeString[data.heap, stringValue];
END
ELSE IF ~copyToList THEN IO.PutChar[fH,space]};
ENDCASE;
END;
CleanUpStream: PROCEDURE[streamHandle: IO.STREAM--MStream.Handle--] RETURNS [--MStream.Handle-- IO.STREAM] = {
streamHandle.Close;
Stream.Delete[streamHandle];
streamHandle ¬ NIL;
RETURN [streamHandle];
}; --of CleanUpStream
ClearString: PROCEDURE[inString: Rope.ROPE] RETURNS [Rope.ROPE ¬ NIL] = {
index: CARDINAL ← 0;
FOR index IN [0..16) DO
inString.text[index] ← ' ;
FOR index IN [0..inString.Length) DO
inString.text[index] ← ' ;
ENDLOOP;
inString.Length ← 0;
RETURN [NIL];
RETURN [inString];
}; --of ClearString
PruneQL: PROCEDURE[set:AdobeOps.SetOfARs, index:CARDINAL] RETURNS [AdobeOps.SetOfARs] =
BEGIN
newSet: AdobeOps.SetOfARs ¬ NIL;
IF set[0].startValue = 0 THEN {
AdobeOps.z.FREE[@set];
RETURN[NIL]};
IF index + 1 = set.len THEN RETURN[set]
ELSE {
newSet ¬ NEW[AdobeOps.SetOfARsObject[index + 1]];
FOR i: CARDINAL IN [0..newSet.len) DO
newSet[i] ¬ set[i];
ENDLOOP;
AdobeOps.z.FREE[@set];
RETURN[newSet]};
END; --of PruneQL
}. . .