home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / amigae / e_v3.2a / rkrmsrc / iffparse / sift.e < prev   
Text File  |  1977-12-31  |  6KB  |  158 lines

  1. -> sift.e - Takes any IFF file and tells you what's in it.  Verifies syntax
  2. ->          and all that cool stuff.
  3. ->
  4. -> Usage: sift -c                ; For clipboard scanning
  5. ->    or  sift <file>            ; For DOS file scanning
  6. ->
  7. -> Reads the specified stream and prints an IFFCheck-like listing of the
  8. -> contents of the IFF file, if any.  Stream is a DOS file for <file>
  9. -> argument, or is the clipboard's primary clip for -c.  This program must be
  10. -> run from a CLI.
  11.  
  12. ->>> Header (globals)
  13. MODULE 'iffparse',
  14.        'devices/clipboard',
  15.        'libraries/iffparse',
  16.        'other/split'
  17.  
  18. ENUM ERR_NONE, ERR_ARGS, ERR_CLIP, ERR_IFF, ERR_LIB, ERR_OIFF, ERR_OPEN,
  19.      ERR_USE
  20.  
  21. RAISE ERR_CLIP IF OpenClipboard()=NIL,
  22.       ERR_IFF  IF AllocIFF()=NIL,
  23.       ERR_LIB  IF OpenLibrary()=NIL,
  24.       ERR_OIFF IF OpenIFF()<>0,
  25.       ERR_OPEN IF Open()=NIL
  26.  
  27. -> E-Note: using argSplit() so one less argument than argv (no command name)
  28. CONST MINARGS=1
  29.  
  30. DEF usage, errormsgs:PTR TO LONG
  31. ->>>
  32.  
  33. ->>> PROC main()
  34. PROC main() HANDLE
  35.   DEF iff=NIL:PTR TO iffhandle, error, cbio, arglist:PTR TO LONG, going=TRUE
  36.   -> E-Note: set-up globals
  37.   usage:='Usage: sift IFFfilename (or -c for clipboard)\n'
  38.   -> Text error messages for possible IFFERR_#? returns from various IFF
  39.   -> routines.  To get the index into this array, take your IFFERR code,
  40.   -> negate it, and subtract one.
  41.   ->  idx = -error - 1;
  42.   errormsgs:=['End of file (not an error).', 'End of context (not an error).',
  43.               'No lexical scope.', 'Insufficient memory.',
  44.               'Stream read error.', 'Stream write error.',
  45.               'Stream seek error.', 'File is corrupt.', 'IFF syntax error.',
  46.               'Not an IFF file.', 'Required call-back hook missing.',
  47.               'Return to client.  You should never see this.']:LONG
  48.   IF NIL=(arglist:=argSplit()) THEN Raise(ERR_ARGS)
  49.   -> If not enough args or "?", print usage
  50.   IF ListLen(arglist)<>MINARGS THEN Raise(ERR_USE)
  51.   IF arglist[][]="?" THEN Raise(ERR_USE)
  52.  
  53.   -> Check to see if we are doing I/O to the Clipboard.
  54.   cbio:=(arglist[][]="-") AND (arglist[][1]="c")
  55.  
  56.   iffparsebase:=OpenLibrary('iffparse.library', 0)
  57.  
  58.   -> Allocate IFF_File OBJECT
  59.   iff:=AllocIFF()
  60.  
  61.   -> Internal support is provided for both AmigaDOS files, and the
  62.   -> clipboard.device.  This bizarre 'IF' statement performs the appropriate
  63.   -> machinations for each case.
  64.   IF cbio
  65.     -> Set up IFF_File for Clipboard I/O.
  66.     iff.stream:=OpenClipboard(PRIMARY_CLIP)
  67.     InitIFFasClip(iff)
  68.   ELSE
  69.     -> Set up IFF_File for AmigaDOS I/O.
  70.     iff.stream:=Open(arglist[], OLDFILE)
  71.     InitIFFasDOS(iff)
  72.   ENDIF
  73.  
  74.   -> Start the IFF transaction.
  75.   OpenIFF(iff, IFFF_READ)
  76.  
  77.   -> E-Note: the going flag makes this easier to understand
  78.   WHILE going
  79.     -> The interesting bit.  IFFPARSE_RAWSTEP permits us to have precision
  80.     -> monitoring of the parsing process, which is necessary if we wish to
  81.     -> print the structure of an IFF file.  ParseIFF() with _RAWSTEP will
  82.     -> return the following things for the following reasons:
  83.     ->
  84.     -> Return code:                 Reason:
  85.     -> 0                            Entered new context.
  86.     -> IFFERR_EOC                   About to leave a context.
  87.     -> IFFERR_EOF                   Encountered end-of-file.
  88.     -> <anything else>              A parsing error.
  89.     error:=ParseIFF(iff, IFFPARSE_RAWSTEP)
  90.  
  91.     -> Since we're only interested in when we enter a context, we 'discard'
  92.     -> end-of-context (_EOC) events.
  93.     IF error=IFFERR_EOC
  94.     ELSEIF error
  95.       -> Leave the loop if there is any other error.
  96.       going:=FALSE
  97.     ELSE
  98.       -> If we get here, error was zero.  Print out the current state of
  99.       -> affairs.
  100.       printTopChunk(iff)
  101.     ENDIF
  102.   ENDWHILE
  103.  
  104.   -> If error was IFFERR_EOF, then the parser encountered the end of the file
  105.   -> without problems.  Otherwise, we print a diagnostic.
  106.   IF error=IFFERR_EOF
  107.     WriteF('File scan complete.\n')
  108.   ELSE
  109.     WriteF('File scan aborted, error \d: \s\n', error, errormsgs[-error-1])
  110.   ENDIF
  111. EXCEPT DO
  112.   IF iff
  113.     -> Terminate the IFF transaction with the stream.
  114.     CloseIFF(iff)
  115.     -> Close the stream itself.
  116.     IF iff.stream
  117.       IF cbio THEN CloseClipboard(iff.stream) ELSE Close(iff.stream)
  118.     ENDIF
  119.     -> Free the IFF_File object itself.
  120.     FreeIFF(iff)
  121.   ENDIF
  122.   IF iffparsebase THEN CloseLibrary(iffparsebase)
  123.   SELECT exception
  124.   CASE ERR_CLIP;  WriteF('Error: could not open clipboard\n')
  125.   CASE ERR_IFF;   WriteF('Error: could not allocate IFF handle\n')
  126.   CASE ERR_LIB;   WriteF('Error: could not open iffparse.library\n')
  127.   CASE ERR_OIFF;  WriteF('Error: could not open IFF handle\n')
  128.   CASE ERR_OPEN;  WriteF('Error: could not open file\n')
  129.   CASE ERR_USE;   WriteF(usage)
  130.   ENDSELECT
  131. ENDPROC
  132. ->>>
  133.  
  134. ->>> PROC printTopChunk(iff:PTR TO iffhandle)
  135. PROC printTopChunk(iff:PTR TO iffhandle)
  136.   DEF top:PTR TO contextnode, i, idbuf[5]:ARRAY
  137.   -> Get a pointer to the context node describing the current context.
  138.   IF NIL=(top:=CurrentChunk(iff)) THEN RETURN
  139.  
  140.   -> Print a series of dots equivalent to the current nesting depth of chunks
  141.   -> processed so far.  This will cause nested chunks to be printed out
  142.   -> indented.
  143.   FOR i:=iff.depth TO 1 STEP -1 DO WriteF('. ')
  144.  
  145.   -> Print out the current chunk's ID and size.
  146.   WriteF('\s \d ', IdtoStr(top.id, idbuf), top.size)
  147.  
  148.   -> Print the current chunk's type, with a newline.
  149.   WriteF('\s\n', IdtoStr(top.type, idbuf))
  150. ENDPROC
  151. ->>>
  152.  
  153. ->>> Version string
  154. -> 2.0 Version string for c:Version to find
  155. vers:
  156.   CHAR 0, '$VER: sift 37.1', 0
  157. ->>>
  158.