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: BOOLEAN ← TRUE]
RETURNS[initialMsg: Rope.ROPE ← NIL] =
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];
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];
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
}. . .