Annotation of researchv10dc/cmd/postscript/grabit/grabit.ps, revision 1.1.1.1

1.1       root        1: %
                      2: % Dump a PostScript object, occasionally in a form that can be sent back
                      3: % through the interpreter. Similiar to Adobe's == procedure, but output
                      4: % is usually easier to read. No binding so operators like rcheck and exec
                      5: % can be conviently redefined.
                      6: %
                      7: 
                      8: /GrabitDict 100 dict dup begin
                      9: 
                     10: /recursive true def
                     11: /scratchstring 200 string def
                     12: /slowdown 100 def
                     13: 
                     14: /column 0 def
                     15: /lastcolumn 80 def
                     16: /level 0 def
                     17: /multiline 100 array def
                     18: /nextname 0 def
                     19: /arraylength 0 def
                     20: /lengthonly false def
                     21: 
                     22: /GrabitSetup {
                     23:        counttomark {OmitNames exch true put} repeat pop
                     24:        0 0 moveto              % for hardcopy output
                     25: } def
                     26: 
                     27: /OmitNames 30 dict def         % ignore these names
                     28: /OtherDicts 200 dict def       % unrecognized dictionaries
                     29: 
                     30: %
                     31: % All strings returned to the host go through Print. First pass through an
                     32: % array has lengthonly set to true.
                     33: %
                     34: 
                     35: /Print {
                     36:        dup type /stringtype ne {scratchstring cvs} if
                     37:        lengthonly {
                     38:                length arraylength add /arraylength exch def
                     39:        }{
                     40:                dup length column add /column exch def
                     41:                print flush
                     42:                slowdown {1 pop} repeat
                     43:        } ifelse
                     44: } def
                     45: 
                     46: /Indent {level {(    ) Print} repeat} def
                     47: /Newline {(\n) Print lengthonly not {/column 0 def} if} def
                     48: 
                     49: /NextLevel {/level level 1 add def multiline level 0 put} def
                     50: /LastLevel {/level level 1 sub def} def
                     51: 
                     52: %
                     53: % Make a unique name for each unrecognized dictionary and remember the name
                     54: % and dictionary in OtherDicts.
                     55: %
                     56: 
                     57: /Register {
                     58:        dup type /dicttype eq {
                     59:                /nextname nextname 1 add def
                     60:                dup (UnknownDict   ) dup
                     61:                (UnknownDict) length nextname (   ) cvs putinterval
                     62:                0 (UnknownDict) length nextname (   ) cvs length add getinterval cvn
                     63:                exch OtherDicts 3 1 roll put
                     64:        } if
                     65: } def
                     66: 
                     67: %
                     68: % Replace array or dictionary values by known names. Lookups are in the
                     69: % standard PostScript dictionaries and in OtherDicts. If found replace
                     70: % the value by the name and make it executable so nametype omits the
                     71: % leading /.
                     72: %
                     73: 
                     74: /Replace {
                     75:        false
                     76:        1 index type /dicttype eq {pop true} if
                     77:        1 index type /arraytype eq 2 index xcheck not and {pop true} if
                     78:        {
                     79:                false
                     80:                [userdict systemdict statusdict serverdict OtherDicts] {
                     81:                        {
                     82:                                3 index eq
                     83:                                        {exch pop exch pop cvx true exit}
                     84:                                        {pop}
                     85:                                ifelse
                     86:                        } forall
                     87:                        dup {exit} if
                     88:                } forall
                     89:                pop
                     90:        } if
                     91: } def
                     92: 
                     93: %
                     94: % Simple type handlers. In some cases (e.g. savetype) what's returned can't
                     95: % be sent back through the interpreter.
                     96: %
                     97: 
                     98: /booleantype {{(true )}{(false )} ifelse Print} def
                     99: /marktype {pop (mark ) Print} def
                    100: /nulltype {pop (null ) Print} def
                    101: /integertype {Print ( ) Print} def
                    102: /realtype {Print ( ) Print} def
                    103: /filetype {pop (-file- ) Print} def
                    104: /fonttype {pop (-fontID- ) Print} def
                    105: /savetype {pop (-saveobj- ) Print} def
                    106: 
                    107: %
                    108: % Special formatting for operators is enabled if the flag in multiline
                    109: % (for the current level) is set to 1. In that case each operator, after
                    110: % being printed, is looked up in OperatorDict. If found the value is used
                    111: % as an index into the OperatorProcs array and the object at that index
                    112: % is retrieved and executed. Currently only used to choose the operators
                    113: % that end a line.
                    114: %
                    115: 
                    116: /operatortype {
                    117:        dup Print ( ) Print
                    118:        multiline level get 1 eq {
                    119:                scratchstring cvs cvn dup OperatorDict exch known {
                    120:                        OperatorDict exch get
                    121:                        OperatorProcs exch get exec
                    122:                }{
                    123:                        pop
                    124:                        column lastcolumn gt {Newline Indent} if
                    125:                } ifelse
                    126:        }{pop} ifelse
                    127: } def
                    128: 
                    129: %
                    130: % Executable names are passed to operatortype. Non-executable names get a
                    131: % leading /.
                    132: %
                    133: 
                    134: /nametype {
                    135:        dup xcheck {
                    136:                operatortype
                    137:        }{
                    138:                (/) Print Print ( ) Print
                    139:        } ifelse
                    140: } def
                    141: 
                    142: %
                    143: % Arrays are processed in two passes. The first computes the length of the
                    144: % string returned to the host without any special formatting. If it extends
                    145: % past the last column special formatting is enabled by setting a flag in
                    146: % array multiline. Arrays are processed in a for loop so the last element
                    147: % easily recognized. At that point special fortmatting is disabled.
                    148: %
                    149: 
                    150: /packedarraytype {arraytype} def
                    151: 
                    152: /arraytype {
                    153:        NextLevel
                    154:        lengthonly not {
                    155:                /lengthonly true def
                    156:                /arraylength 0 def
                    157:                dup dup type exec
                    158:                arraylength 20 gt arraylength column add lastcolumn gt and {
                    159:                        multiline level 1 put
                    160:                } if
                    161:                /lengthonly false def
                    162:        } if
                    163: 
                    164:        dup rcheck not {
                    165:                (-array- ) Print pop
                    166:        }{
                    167:                dup xcheck {({)}{([)} ifelse Print
                    168:                multiline level get 0 ne {Newline Indent}{( ) Print} ifelse
                    169:                0 1 2 index length 1 sub {
                    170:                        2 copy exch length 1 sub eq multiline level get 1 eq and {
                    171:                                multiline level 2 put
                    172:                        } if
                    173:                        2 copy get exch pop
                    174:                        dup type /dicttype eq {
                    175:                                Replace
                    176:                                dup type /dicttype eq {
                    177:                                        dup Register Replace
                    178:                                        recursive {
                    179:                                                2 copy cvlit
                    180:                                                /def load 3 1 roll
                    181:                                                count 3 roll
                    182:                                        } if
                    183:                                        exch pop
                    184:                                } if
                    185:                        } if
                    186:                        dup type exec
                    187:                        dup xcheck not multiline level get 1 eq and {
                    188:                                0 index type /arraytype eq
                    189:                                1 index type /packedarray eq or
                    190:                                1 index type /stringtype eq or {Newline Indent} if
                    191:                        } if
                    192:                } for
                    193:                multiline level get 0 ne {Newline LastLevel Indent NextLevel} if
                    194:                xcheck {(} )}{(] )} ifelse Print
                    195:        } ifelse
                    196:        LastLevel
                    197: } def
                    198: 
                    199: %
                    200: % Dictionary handler. Try to replace the value by a name before processing
                    201: % the dictionary.
                    202: %
                    203: 
                    204: /dicttype {
                    205:        dup
                    206:        rcheck not {
                    207:                (-dictionary- ) Print pop
                    208:        }{
                    209:                dup maxlength Print ( dict dup begin) Print Newline
                    210:                NextLevel
                    211:                {
                    212:                        1 index OmitNames exch known {
                    213:                                pop pop
                    214:                        }{
                    215:                                Indent
                    216:                                Replace         % arrays and dicts by known names
                    217:                                Register        % new dictionaries in OtherDicts
                    218:                                exch
                    219:                                cvlit dup type exec     % key first - force a /
                    220:                                dup type exec           % then the value
                    221:                                (def) Print Newline
                    222:                        } ifelse
                    223:                } forall
                    224:                LastLevel
                    225:                Indent
                    226:                (end ) Print
                    227:        } ifelse
                    228: } def
                    229: 
                    230: %
                    231: % Strings containing characters not in AsciiDict are returned in hex. All
                    232: % others are ASCII strings and use AsciiDict for character mapping.
                    233: %
                    234: 
                    235: /onecharstring ( ) def
                    236: /twocharstring (  ) def
                    237: 
                    238: /stringtype {
                    239:        dup
                    240:        rcheck not {
                    241:                (-string- ) Print
                    242:        }{
                    243:                /hexit false def
                    244:                dup {
                    245:                        onecharstring 0 3 -1 roll put
                    246:                        AsciiDict onecharstring cvn known not {
                    247:                                /hexit true def exit
                    248:                        } if
                    249:                } forall
                    250: 
                    251:                hexit {(<)}{(\()} ifelse Print
                    252:                0 1 2 index length 1 sub {
                    253:                        2 copy 1 getinterval exch pop
                    254:                        hexit {
                    255:                                0 get /n exch def
                    256:                                n -4 bitshift 16#F and 16 twocharstring cvrs pop
                    257:                                n 16#F and twocharstring 1 1 getinterval 16 exch cvrs pop
                    258:                                twocharstring
                    259:                        }{cvn AsciiDict exch get} ifelse
                    260:                        Print
                    261:                        column lastcolumn gt {
                    262:                                hexit not {(\\) Print} if
                    263:                                Newline
                    264:                        } if
                    265:                } for
                    266:                hexit {(> )}{(\) )} ifelse Print
                    267:        } ifelse
                    268:        pop
                    269: } def
                    270: 
                    271: %
                    272: % ASCII characters and replacement strings. Ensures the returned string will
                    273: % reproduce the original when passed through the scanner. Strings containing
                    274: % characters not in this list should be returned as hex strings.
                    275: %
                    276: 
                    277: /AsciiDict 128 dict dup begin
                    278:        (\n) cvn (\\n) def
                    279:        (\r) cvn (\\r) def
                    280:        (\t) cvn (\\t) def
                    281:        (\b) cvn (\\b) def
                    282:        (\f) cvn (\\f) def
                    283:        ( ) cvn ( ) def
                    284:        (!) cvn (!) def
                    285:        (") cvn (") def
                    286:        (#) cvn (#) def
                    287:        ($) cvn ($) def
                    288:        (%) cvn (\\%) def
                    289:        (&) cvn (&) def
                    290:        (') cvn (') def
                    291:        (\() cvn (\\\() def
                    292:        (\)) cvn (\\\)) def
                    293:        (*) cvn (*) def
                    294:        (+) cvn (+) def
                    295:        (,) cvn (,) def
                    296:        (-) cvn (-) def
                    297:        (.) cvn (.) def
                    298:        (/) cvn (/) def
                    299:        (0) cvn (0) def
                    300:        (1) cvn (1) def
                    301:        (2) cvn (2) def
                    302:        (3) cvn (3) def
                    303:        (4) cvn (4) def
                    304:        (5) cvn (5) def
                    305:        (6) cvn (6) def
                    306:        (7) cvn (7) def
                    307:        (8) cvn (8) def
                    308:        (9) cvn (9) def
                    309:        (:) cvn (:) def
                    310:        (;) cvn (;) def
                    311:        (<) cvn (<) def
                    312:        (=) cvn (=) def
                    313:        (>) cvn (>) def
                    314:        (?) cvn (?) def
                    315:        (@) cvn (@) def
                    316:        (A) cvn (A) def
                    317:        (B) cvn (B) def
                    318:        (C) cvn (C) def
                    319:        (D) cvn (D) def
                    320:        (E) cvn (E) def
                    321:        (F) cvn (F) def
                    322:        (G) cvn (G) def
                    323:        (H) cvn (H) def
                    324:        (I) cvn (I) def
                    325:        (J) cvn (J) def
                    326:        (K) cvn (K) def
                    327:        (L) cvn (L) def
                    328:        (M) cvn (M) def
                    329:        (N) cvn (N) def
                    330:        (O) cvn (O) def
                    331:        (P) cvn (P) def
                    332:        (Q) cvn (Q) def
                    333:        (R) cvn (R) def
                    334:        (S) cvn (S) def
                    335:        (T) cvn (T) def
                    336:        (U) cvn (U) def
                    337:        (V) cvn (V) def
                    338:        (W) cvn (W) def
                    339:        (X) cvn (X) def
                    340:        (Y) cvn (Y) def
                    341:        (Z) cvn (Z) def
                    342:        ([) cvn ([) def
                    343:        (\\) cvn (\\\\) def
                    344:        (]) cvn (]) def
                    345:        (^) cvn (^) def
                    346:        (_) cvn (_) def
                    347:        (`) cvn (`) def
                    348:        (a) cvn (a) def
                    349:        (b) cvn (b) def
                    350:        (c) cvn (c) def
                    351:        (d) cvn (d) def
                    352:        (e) cvn (e) def
                    353:        (f) cvn (f) def
                    354:        (g) cvn (g) def
                    355:        (h) cvn (h) def
                    356:        (i) cvn (i) def
                    357:        (j) cvn (j) def
                    358:        (k) cvn (k) def
                    359:        (l) cvn (l) def
                    360:        (m) cvn (m) def
                    361:        (n) cvn (n) def
                    362:        (o) cvn (o) def
                    363:        (p) cvn (p) def
                    364:        (q) cvn (q) def
                    365:        (r) cvn (r) def
                    366:        (s) cvn (s) def
                    367:        (t) cvn (t) def
                    368:        (u) cvn (u) def
                    369:        (v) cvn (v) def
                    370:        (w) cvn (w) def
                    371:        (x) cvn (x) def
                    372:        (y) cvn (y) def
                    373:        (z) cvn (z) def
                    374:        ({) cvn ({) def
                    375:        (|) cvn (|) def
                    376:        (}) cvn (}) def
                    377:        (~) cvn (~) def
                    378: end def
                    379: 
                    380: %
                    381: % OperatorDict can help format procedure listings. The value assigned to each
                    382: % name is used as an index into the OperatorProcs array. The procedure at that
                    383: % index is fetched and executed after the named operator is printed. What's in
                    384: % OperatorDict is a matter of taste rather than correctness. The default list
                    385: % represents our choice of which of Adobe's operators should end a line.
                    386: %
                    387: 
                    388: /OperatorProcs [{} {Newline Indent}] def
                    389: 
                    390: /OperatorDict 250 dict def
                    391: 
                    392: OperatorDict   /arc                    1 put
                    393: OperatorDict   /arcn                   1 put
                    394: OperatorDict   /ashow                  1 put
                    395: OperatorDict   /awidthshow             1 put
                    396: OperatorDict   /banddevice             1 put
                    397: OperatorDict   /begin                  1 put
                    398: OperatorDict   /charpath               1 put
                    399: OperatorDict   /clear                  1 put
                    400: OperatorDict   /cleardictstack         1 put
                    401: OperatorDict   /cleartomark            1 put
                    402: OperatorDict   /clip                   1 put
                    403: OperatorDict   /clippath               1 put
                    404: OperatorDict   /closefile              1 put
                    405: OperatorDict   /closepath              1 put
                    406: OperatorDict   /concat                 1 put
                    407: OperatorDict   /copypage               1 put
                    408: OperatorDict   /curveto                1 put
                    409: OperatorDict   /def                    1 put
                    410: OperatorDict   /end                    1 put
                    411: OperatorDict   /eoclip                 1 put
                    412: OperatorDict   /eofill                 1 put
                    413: OperatorDict   /erasepage              1 put
                    414: OperatorDict   /exec                   1 put
                    415: OperatorDict   /exit                   1 put
                    416: OperatorDict   /fill                   1 put
                    417: OperatorDict   /flattenpath            1 put
                    418: OperatorDict   /flush                  1 put
                    419: OperatorDict   /flushfile              1 put
                    420: OperatorDict   /for                    1 put
                    421: OperatorDict   /forall                 1 put
                    422: OperatorDict   /framedevice            1 put
                    423: OperatorDict   /grestore               1 put
                    424: OperatorDict   /grestoreall            1 put
                    425: OperatorDict   /gsave                  1 put
                    426: OperatorDict   /handleerror            1 put
                    427: OperatorDict   /if                     1 put
                    428: OperatorDict   /ifelse                 1 put
                    429: OperatorDict   /image                  1 put
                    430: OperatorDict   /imagemask              1 put
                    431: OperatorDict   /initclip               1 put
                    432: OperatorDict   /initgraphics           1 put
                    433: OperatorDict   /initmatrix             1 put
                    434: OperatorDict   /kshow                  1 put
                    435: OperatorDict   /lineto                 1 put
                    436: OperatorDict   /loop                   1 put
                    437: OperatorDict   /moveto                 1 put
                    438: OperatorDict   /newpath                1 put
                    439: OperatorDict   /nulldevice             1 put
                    440: OperatorDict   /pathforall             1 put
                    441: OperatorDict   /print                  1 put
                    442: OperatorDict   /prompt                 1 put
                    443: OperatorDict   /put                    1 put
                    444: OperatorDict   /putinterval            1 put
                    445: OperatorDict   /quit                   1 put
                    446: OperatorDict   /rcurveto               1 put
                    447: OperatorDict   /renderbands            1 put
                    448: OperatorDict   /repeat                 1 put
                    449: OperatorDict   /resetfile              1 put
                    450: OperatorDict   /restore                1 put
                    451: OperatorDict   /reversepath            1 put
                    452: OperatorDict   /rlineto                1 put
                    453: OperatorDict   /rmoveto                1 put
                    454: OperatorDict   /rotate                 1 put
                    455: OperatorDict   /run                    1 put
                    456: OperatorDict   /scale                  1 put
                    457: OperatorDict   /setcachedevice         1 put
                    458: OperatorDict   /setcachelimit          1 put
                    459: OperatorDict   /setcacheparams         1 put
                    460: OperatorDict   /setcharwidth           1 put
                    461: OperatorDict   /setdash                1 put
                    462: OperatorDict   /setdefaulttimeouts     1 put
                    463: OperatorDict   /setdostartpage         1 put
                    464: OperatorDict   /seteescratch           1 put
                    465: OperatorDict   /setflat                1 put
                    466: OperatorDict   /setfont                1 put
                    467: OperatorDict   /setgray                1 put
                    468: OperatorDict   /sethsbcolor            1 put
                    469: OperatorDict   /setidlefonts           1 put
                    470: OperatorDict   /setjobtimeout          1 put
                    471: OperatorDict   /setlinecap             1 put
                    472: OperatorDict   /setlinejoin            1 put
                    473: OperatorDict   /setlinewidth           1 put
                    474: OperatorDict   /setmargins             1 put
                    475: OperatorDict   /setmatrix              1 put
                    476: OperatorDict   /setmiterlimit          1 put
                    477: OperatorDict   /setpacking             1 put
                    478: OperatorDict   /setpagetype            1 put
                    479: OperatorDict   /setprintname           1 put
                    480: OperatorDict   /setrgbcolor            1 put
                    481: OperatorDict   /setsccbatch            1 put
                    482: OperatorDict   /setsccinteractive      1 put
                    483: OperatorDict   /setscreen              1 put
                    484: OperatorDict   /settransfer            1 put
                    485: OperatorDict   /show                   1 put
                    486: OperatorDict   /showpage               1 put
                    487: OperatorDict   /start                  1 put
                    488: OperatorDict   /stop                   1 put
                    489: OperatorDict   /store                  1 put
                    490: OperatorDict   /stroke                 1 put
                    491: OperatorDict   /strokepath             1 put
                    492: OperatorDict   /translate              1 put
                    493: OperatorDict   /widthshow              1 put
                    494: OperatorDict   /write                  1 put
                    495: OperatorDict   /writehexstring         1 put
                    496: OperatorDict   /writestring            1 put
                    497: 
                    498: end def
                    499: 
                    500: %
                    501: % Put an object on the stack and call Grabit. Output continues until stack
                    502: % is empty. For example,
                    503: %
                    504: %              /letter load Grabit
                    505: %
                    506: % prints a listing of the letter procedure.
                    507: %
                    508: 
                    509: /Grabit {
                    510:        /saveobj save def
                    511:        GrabitDict begin
                    512:                {
                    513:                        count 0 eq {exit} if
                    514:                        count {dup type exec} repeat
                    515:                        (\n) print flush
                    516:                } loop
                    517:        end
                    518:        currentpoint                    % for hardcopy output
                    519:        saveobj restore
                    520:        moveto
                    521: } def
                    522: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.