DIRECTORY IPScan, FS USING [Error, FileInfo], IPMaster, Rope USING [Find, Run, Size, Substr], RopeFile USING [Create]; IPScanImpl: CEDAR PROGRAM IMPORTS FS, IPMaster, Rope, RopeFile EXPORTS IPScan ~ BEGIN OPEN IPScan; stackMax: NAT ~ 1000; OpAction: TYPE ~ RECORD [pop: NAT _ stackMax, push, requireStackEmpty: BOOL _ FALSE]; opAction: ARRAY Op OF OpAction ~ [ abs: [pop: 1, push: TRUE], add: [pop: 2, push: TRUE], alternatemetrics: [], and: [pop: 2, push: TRUE], arcto: [pop: 5, push: TRUE], beginBlock: [pop: 0, requireStackEmpty: TRUE], beginBody: [pop: 0, requireStackEmpty: TRUE], ceiling: [pop: 1, push: TRUE], clipoutline: [pop: 1], cliprectangle: [pop: 4], concat: [pop: 2, push: TRUE], concatt: [pop: 1], conicto: [pop: 6, push: TRUE], contentInstructions: [pop: 0, requireStackEmpty: TRUE], copy: [], correct: [pop: 0, requireStackEmpty: TRUE], correctmask: [pop: 0], correctspace: [pop: 2], count: [pop: 0, push: TRUE], curveto: [pop: 7, push: TRUE], div: [pop: 2, push: TRUE], do: [], dosave: [], dosaveall: [], dosavesimplebody: [pop: 0, requireStackEmpty: TRUE], dup: [pop: 0, push: TRUE], endBlock: [pop: 0], endBody: [pop: 0], eq: [pop: 2, push: TRUE], error: [pop: 2], exch: [], extractpixelarray: [pop: 2, push: TRUE], fget: [pop: 1, push: TRUE], findcolor: [pop: 1, push: TRUE], findcolormodeloperator: [pop: 1, push: TRUE], findcoloroperator: [pop: 1, push: TRUE], finddecompressor: [pop: 1, push: TRUE], findfont: [pop: 1, push: TRUE], findoperator: [pop: 1, push: TRUE], floor: [pop: 1, push: TRUE], fset: [pop: 2], ge: [pop: 2, push: TRUE], get: [pop: 2, push: TRUE], getcp: [], getp: [pop: 2, push: TRUE], getprop: [], gt: [pop: 2, push: TRUE], if: [pop: 1, requireStackEmpty: TRUE], ifcopy: [], ifelse: [pop: 1, requireStackEmpty: TRUE], iget: [pop: 1, push: TRUE], iset: [pop: 2], lineto: [pop: 3, push: TRUE], linetox: [pop: 2, push: TRUE], linetoy: [pop: 2, push: TRUE], makefont: [pop: 1, push: TRUE], makegray: [pop: 1, push: TRUE], makeoutline: [pop: 1, push: TRUE], --Special case! makeoutlineodd: [pop: 1, push: TRUE], --Special case! makepixelarray: [pop: 7, push: TRUE], makesampledblack: [pop: 3, push: TRUE], makesampledcolor: [pop: 3, push: TRUE], makesimpleco: [pop: 0], maket: [pop: 6, push: TRUE], makevec: [pop: 1, push: TRUE], --Special case! makeveclu: [], mark: [], maskchar: [pop: 1], --Actually [2, 1], but the push is the fd already on the stack maskdashedstroke: [pop: 4], maskfill: [pop: 1], maskfillparity: [pop: 1], --?? maskpixel: [pop: 1], maskrectangle: [pop: 4], maskstroke: [pop: 1], maskstrokeclosed: [pop: 1], masktrapezoidx: [pop: 6], masktrapezoidy: [pop: 6], maskunderline: [pop: 2], maskvector: [pop: 4], mergeprop: [pop: 2, push: TRUE], mod: [pop: 2, push: TRUE], modifyfont: [pop: 2, push: TRUE], move: [pop: 0], moveto: [pop: 2, push: TRUE], mul: [pop: 2, push: TRUE], neg: [pop: 1, push: TRUE], nil: [], nop: [pop: 0], not: [pop: 1, push: TRUE], or: [pop: 2, push: TRUE], pop: [pop: 1], rem: [pop: 2, push: TRUE], roll: [], rotate: [pop: 1, push: TRUE], round: [pop: 1, push: TRUE], scale: [pop: 1, push: TRUE], scale2: [pop: 2, push: TRUE], setcorrectmeasure: [pop: 2], setcorrecttolerance: [pop: 2], setfont: [pop: 1], setgray: [pop: 1], setsampledblack: [pop: 3], setsampledcolor: [pop: 3], setxrel: [pop: 1], setxy: [pop: 2], setxyrel: [pop: 2], setyrel: [pop: 1], shape: [], show: [pop: 1], showandfixedxrel: [pop: 2], showandxrel: [pop: 1], showbackward: [pop: 1], --?? space: [pop: 1], startunderline: [pop: 0], sub: [pop: 2, push: TRUE], trans: [pop: 0], translate: [pop: 2, push: TRUE], trunc: [pop: 1, push: TRUE], type: [pop: 1, push: TRUE], unmark: [], unmark0: [pop: 1] ]; allSeqs: PUBLIC LIST OF Seq ~ LIST [sequenceString, sequenceInteger, sequenceInsertMaster, sequenceRational, sequenceIdentifier, sequenceComment, sequenceContinued, sequenceLargeVector, sequencePackedPixelVector, sequenceCompressedPixelVector, sequenceInsertFile, sequenceAdaptivePixelVector, sequenceCCITT4PixelVector]; allOps: PUBLIC LIST OF Op ~ LIST [ nil, get, makeveclu, makevec, shape, getprop, getp, mergeprop, fget, fset, makesimpleco, do, dosave, dosaveall, dosavesimplebody, findoperator, pop, copy, dup, roll, exch, mark, unmark, unmark0, count, nop, error, if, ifelse, ifcopy, eq, gt, ge, and, or, not, type, add, sub, neg, abs, floor, ceiling, trunc, round, mul, div, mod, rem, iget, iset, maket, translate, rotate, scale, scale2, concat, concatt, move, trans, setxy, setxyrel, setxrel, setyrel, getcp, makepixelarray, extractpixelarray, finddecompressor, makegray, findcolor, findcoloroperator, findcolormodeloperator, makesampledcolor, makesampledblack, setgray, setsampledcolor, setsampledblack, moveto, lineto, linetox, linetoy, curveto, conicto, arcto, makeoutline, makeoutlineodd, maskfill, maskfillparity, maskrectangle, startunderline, maskunderline, masktrapezoidx, masktrapezoidy, maskstroke, maskstrokeclosed, maskvector, maskdashedstroke, maskpixel, clipoutline, cliprectangle, maskchar, makefont, findfont, modifyfont, alternatemetrics, setfont, show, showbackward, showandxrel, showandfixedxrel, correctmask, correctspace, space, setcorrectmeasure, setcorrecttolerance, correct, beginBody, endBody, beginBlock, endBlock, contentInstructions ]; maxHeaderLength: INT _ 200; IPRopeFromName: PUBLIC PROC [xeroxName: ROPE] RETURNS [header, ip: ROPE] ~ { prefix: ROPE ~ "Interpress/Xerox/"; inFullFName: ROPE ~ FS.FileInfo[xeroxName].fullFName; inRope: ROPE ~ RopeFile.Create[name: inFullFName, raw: TRUE]; headerLength: INT ~ Rope.Find[Rope.Substr[inRope, 0, maxHeaderLength], " "]; IF headerLength<0 OR Rope.Run[s1: inRope, s2: prefix] # Rope.Size[prefix] THEN FS.Error[error: [group: user, code: $NotIP, explanation: "Not an interpress master."]] ELSE RETURN [ header: Rope.Substr[inRope, 0, headerLength], ip: Rope.Substr[inRope, headerLength+1] ]; }; ScanRope: PUBLIC PROC [ip: ROPE, ops: LIST OF Op _ NIL, seqs: LIST OF Seq _ NIL, nums: BOOL _ FALSE, action: ScanProc] ~ { stopIndex: INT ~ ip.Size[]; earlyQuit: BOOL _ FALSE; index: INT _ 0; seqIndex, tokenIndex: INT _ INT.LAST; num: INTEGER _ stackMax; seq: Seq _ nil; token: IPMaster.Token _ []; stk: ARRAY [0..stackMax) OF INT; --For interpress stack objects, starting pos to build object stkSize: NAT _ 0; do: RECORD [ops: ARRAY Op OF BOOL, seqs: ARRAY Seq OF BOOL, nums: BOOL] _ [ALL[FALSE], ALL[FALSE], nums]; FOR each: LIST OF Op _ ops, each.rest UNTIL each=NIL DO do.ops[each.first] _ TRUE; ENDLOOP; FOR each: LIST OF Seq _ seqs, each.rest UNTIL each=NIL DO do.seqs[each.first] _ TRUE; ENDLOOP; WHILE index < stopIndex DO tokenIndex _ index; [token, index] _ IPMaster.GetToken[encoding: ip, start: index]; IF seq#nil THEN { IF token.seq=sequenceContinued THEN { index _ index + token.len; LOOP; } ELSE { IF do.seqs[seq] THEN earlyQuit _ action[min: seqIndex, max: tokenIndex, seq: seq]; IF earlyQuit THEN EXIT; seq _ nil; }; }; stk[stkSize] _ tokenIndex; --This is above the top of the stack SELECT token.type FROM op => { op: IPMaster.Op ~ IPMaster.OpFromEncodingValue[token.op]; pop: NAT ~ opAction[op].pop + (SELECT op FROM makeoutline, makeoutlineodd, makevec => num, ENDCASE => 0 ); punt: BOOL _ stkSize < pop OR (opAction[op].requireStackEmpty AND stkSize > pop); min: INT ~ IF punt THEN tokenIndex ELSE stk[stkSize _ stkSize-pop]; IF do.ops[op] THEN earlyQuit _ action[min: min, max: index, op: op, punt: punt]; IF earlyQuit THEN EXIT; IF punt THEN stkSize _ 0; SELECT TRUE FROM punt => stkSize _ 0; opAction[op].push => stkSize _ stkSize+1; --N.B. no push on punts ENDCASE; }; num => { num _ token.num; stkSize _ stkSize+1; IF do.nums THEN earlyQuit _ action[min: tokenIndex, max: index, num: num]; IF earlyQuit THEN EXIT; }; seq => { punt: BOOL _ FALSE; index _ index + token.len; seqIndex _ tokenIndex; SELECT seq _ token.seq FROM sequenceAdaptivePixelVector, sequenceCCITT4PixelVector, sequenceCompressedPixelVector, sequenceIdentifier, sequenceInteger, sequenceLargeVector, sequencePackedPixelVector, sequenceRational, sequenceString => stkSize _ stkSize+1; --Push sequenceInsertFile, sequenceInsertMaster => { punt _ TRUE; stkSize _ 0; }; sequenceComment => NULL; --Ignore nil, sequenceContinued => ERROR; ENDCASE => ERROR; }; ENDCASE => ERROR; ENDLOOP; }; END. "IPScanImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Eric Nickell, November 22, 1988 4:10:08 am PST Bob Coleman, April 23, 1990 4:45:45 pm PDT BASE primitives IMAGE primitives Symbols Establish the arrays we'll use to determine whether or not to Main Loop: Κ :˜™Icode™˜RKšœ˜Kšœ˜KšœŸ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœœ˜ Kšœœ˜Kšœœ˜!Kšœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœ˜Kšœ˜Kšœœ˜Kšœœ˜Kšœ˜Kšœœ˜Kšœ ˜ Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜KšœŸ˜Kšœ˜Kšœ˜Kšœœ˜Kšœ˜Kšœœ˜ Kšœœ˜Kšœœ˜Kšœ ˜ Kšœ˜Kšœ˜K˜—Kš œ œœœœž˜ΐš œœœœœ˜"Kšœ˜KšΠbkœ ™KšœF˜FKšœE˜EKšœF˜FKšœ4˜4KšœF˜FKš œ ™Kšœ=˜=Kšœ@˜@Kšœ5˜5Kšœ@˜@KšœO˜OKšœ;˜;KšœF˜FKšœ?˜?KšœG˜GKšœ˜KšœE˜EKšœ3˜3KšœS˜SKšœ™Kšœ=˜=K˜K˜—Kšœœ˜š Οnœ œ œœœ˜LKšœœ˜#Kšœ œœ˜5Kšœœ+œ˜=Kšœœ;˜Lšœœ5˜IK•StartOfExpansion[error: FS.ErrorDesc]šœœT˜[šœœ˜ Kšœ-˜-Kšœ'˜'Kšœ˜——K˜K˜—š‘œœœœœœœœœœœœ˜zKšœ œ ˜Kšœ œœ˜Kšœœ˜Kšœœœœ˜%Kšœœ ˜K˜K˜KšœœœœŸ<˜]Kšœ œ˜K™>Kšœœœœœœœœœœœœœ ˜iš œœœœœ˜7Kšœœ˜Kšœ˜—š œœœœœ˜9Kšœœ˜Kšœ˜—K™ šœ˜K˜K˜?šœ œ˜šœ˜šœ˜K˜Kšœ˜Kšœ˜—šœ˜Kšœœ>˜RKšœ œœ˜K˜ Kšœ˜——K˜—KšœŸ$˜?šœ ˜šœ˜K˜9šœœœ˜-K˜,Kšœ˜ Kšœ˜—Kšœœœ!œ˜QKš œœœœ œ˜CKšœ œ>˜PKšœ œœ˜Kšœœ ˜šœœ˜Kšœ˜Kšœ*Ÿ˜AKšœ˜—Kšœ˜—šœ˜K˜Kšœ˜Kšœ œ;˜JKšœ œœ˜Kšœ˜—šœ˜Kšœœœ˜K˜K˜šœ˜KšœεŸ˜λšœ-˜-Kšœœ˜ K˜ K˜—KšœœŸ˜"Kšœœ˜ Kšœœ˜—Kšœ˜—Kšœœ˜—Kšœ˜—K˜K˜——K˜Kšœ˜—…— 8+”