home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / TRSICAT.LZX / CATS_CD2_TRSI / Reference_Library / lib_examples / Sift.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-21  |  5.5 KB  |  212 lines

  1. ;/* sift.c - Execute me to compile me with SAS C 5.10
  2. LC -b1 -cfistq -v -j73 sift.c
  3. Blink FROM LIB:c.o,sift.o TO sift LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. quit
  5. *
  6. * Sift.c lists the type and size of every chunk in an IFF file and
  7. * checks the IFF file for correct syntax.  You should use Sift to
  8. * check IFF files created by your programs.
  9. *
  10. * sift.c:    Takes any IFF file and tells you what's in it.  Verifies syntax and all that cool stuff.
  11. *
  12. * Usage: sift -c        ; For clipboard scanning
  13. *    or  sift <file>        ; For DOS file scanning
  14. *
  15. * Reads the specified stream and prints an IFFCheck-like listing of the contents of the IFF file, if any.
  16. * Stream is a DOS file for <file> argument, or is the clipboard's primary clip for -c.
  17. * This program must be run from a CLI.
  18. *
  19. */
  20.  
  21. #include <exec/types.h>
  22. #include <exec/memory.h>
  23. #include <libraries/dos.h>
  24. #include <libraries/iffparse.h>
  25. #include <clib/exec_protos.h>
  26. #include <clib/dos_protos.h>
  27. #include <clib/iffparse_protos.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31.  
  32. #ifdef LATTICE
  33. int CXBRK(void) { return(0); }     /* Disable Lattice CTRL/C handling */
  34. int chkabort(void) { return(0); }  /* really */
  35. #endif
  36.  
  37. #define MINARGS 2
  38.  
  39. UBYTE vers[] = "\0$VER: sift 37.1";       /* 2.0 Version string for c:Version to find */
  40. UBYTE usage[] = "Usage: sift IFFfilename (or -c for clipboard)";
  41.  
  42. void PrintTopChunk (struct IFFHandle *);  /* proto for our function */
  43.  
  44. /*
  45.  * Text error messages for possible IFFERR_#? returns from various IFF routines.  To get the index into
  46.  * this array, take your IFFERR code, negate it, and subtract one.
  47.  *  idx = -error - 1;
  48.  */
  49. char    *errormsgs[] = {
  50.     "End of file (not an error).", "End of context (not an error).", "No lexical scope.",
  51.     "Insufficient memory.", "Stream read error.", "Stream write error.",
  52.     "Stream seek error.", "File is corrupt.", "IFF syntax error.",
  53.     "Not an IFF file.", "Required call-back hook missing.", "Return to client.  You should never see this."
  54. };
  55.  
  56. struct Library *IFFParseBase;
  57.  
  58. void main(int argc, char **argv)
  59. {
  60.     struct IFFHandle    *iff = NULL;
  61.     long        error;
  62.     short        cbio;
  63.  
  64.         /* if not enough args or '?', print usage */
  65.         if(((argc)&&(argc<MINARGS))||(argv[argc-1][0]=='?'))
  66.         {
  67.             printf("%s\n",usage);
  68.             goto bye;
  69.             }
  70.  
  71.     /* Check to see if we are doing I/O to the Clipboard. */
  72.     cbio = (argv[1][0] == '-'  &&  argv[1][1] == 'c');
  73.  
  74.     if (!(IFFParseBase = OpenLibrary ("iffparse.library", 0L)))
  75.         {
  76.         puts("Can't open iff parsing library.");
  77.         goto bye;
  78.         }
  79.  
  80.     /* Allocate IFF_File structure. */
  81.     if (!(iff = AllocIFF ()))
  82.         {
  83.         puts ("AllocIFF() failed.");
  84.         goto bye;
  85.         }
  86.  
  87.     /*
  88.      * Internal support is provided for both AmigaDOS files, and the clipboard.device.  This bizarre
  89.      * 'if' statement performs the appropriate machinations for each case.
  90.      */
  91.     if (cbio)
  92.         {
  93.         /*
  94.          * Set up IFF_File for Clipboard I/O.
  95.          */
  96.         if (!(iff->iff_Stream =
  97.                 (ULONG) OpenClipboard (PRIMARY_CLIP)))
  98.             {
  99.             puts ("Clipboard open failed.");
  100.             goto bye;
  101.             }
  102.         InitIFFasClip (iff);
  103.         }
  104.     else
  105.         {
  106.         /* Set up IFF_File for AmigaDOS I/O.  */
  107.         if (!(iff->iff_Stream = Open (argv[1], MODE_OLDFILE)))
  108.             {
  109.             puts ("File open failed.");
  110.             goto bye;
  111.             }
  112.         InitIFFasDOS (iff);
  113.         }
  114.  
  115.     /* Start the IFF transaction. */
  116.     if (error = OpenIFF (iff, IFFF_READ))
  117.         {
  118.         puts ("OpenIFF failed.");
  119.         goto bye;
  120.         }
  121.  
  122.     while (1)
  123.         {
  124.         /*
  125.          * The interesting bit.  IFFPARSE_RAWSTEP permits us to have precision monitoring of the
  126.          * parsing process, which is necessary if we wish to print the structure of an IFF file.
  127.          * ParseIFF() with _RAWSTEP will return the following things for the following reasons:
  128.          *
  129.          * Return code:            Reason:
  130.          * 0                Entered new context.
  131.          * IFFERR_EOC            About to leave a context.
  132.          * IFFERR_EOF            Encountered end-of-file.
  133.          * <anything else>        A parsing error.
  134.          */
  135.         error = ParseIFF (iff, IFFPARSE_RAWSTEP);
  136.  
  137.         /*
  138.          * Since we're only interested in when we enter a context, we "discard" end-of-context
  139.          * (_EOC) events.
  140.          */
  141.         if (error == IFFERR_EOC)
  142.             continue;
  143.         else if (error)
  144.             /*
  145.              * Leave the loop if there is any other error.
  146.              */
  147.             break;
  148.  
  149.  
  150.         /* If we get here, error was zero. Print out the current state of affairs. */
  151.         PrintTopChunk (iff);
  152.         }
  153.  
  154.     /*
  155.      * If error was IFFERR_EOF, then the parser encountered the end of
  156.      * the file without problems.  Otherwise, we print a diagnostic.
  157.      */
  158.     if (error == IFFERR_EOF)
  159.         puts ("File scan complete.");
  160.     else
  161.         printf ("File scan aborted, error %ld: %s\n",
  162.             error, errormsgs[-error - 1]);
  163.  
  164. bye:
  165.     if (iff) {
  166.         /* Terminate the IFF transaction with the stream.  Free all associated structures. */
  167.         CloseIFF (iff);
  168.  
  169.         /*
  170.          * Close the stream itself.
  171.          */
  172.         if (iff->iff_Stream)
  173.             if (cbio)
  174.                 CloseClipboard ((struct ClipboardHandle *)
  175.                         iff->iff_Stream);
  176.             else
  177.                 Close (iff->iff_Stream);
  178.  
  179.         /* Free the IFF_File structure itself. */
  180.         FreeIFF (iff);
  181.         }
  182.     if (IFFParseBase)    CloseLibrary (IFFParseBase);
  183.  
  184.     exit (RETURN_OK);
  185. }
  186.  
  187. void
  188. PrintTopChunk (iff)
  189. struct IFFHandle *iff;
  190. {
  191.     struct ContextNode    *top;
  192.     short            i;
  193.     char            idbuf[5];
  194.  
  195.     /* Get a pointer to the context node describing the current context. */
  196.     if (!(top = CurrentChunk (iff)))
  197.         return;
  198.  
  199.     /*
  200.      * Print a series of dots equivalent to the current nesting depth of chunks processed so far.
  201.      * This will cause nested chunks to be printed out indented.
  202.      */
  203.     for (i = iff->iff_Depth;  i--; )
  204.         printf (". ");
  205.  
  206.     /* Print out the current chunk's ID and size. */
  207.     printf ("%s %ld ", IDtoStr (top->cn_ID, idbuf), top->cn_Size);
  208.  
  209.     /* Print the current chunk's type, with a newline. */
  210.     puts (IDtoStr (top->cn_Type, idbuf));
  211. }
  212.