home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume36
/
chiaro
/
part16
< prev
next >
Wrap
Text File
|
1993-03-26
|
56KB
|
1,795 lines
Newsgroups: comp.sources.misc
From: jwbirdsa@picarefy.picarefy.com (James W. Birdsall)
Subject: v36i086: chiaro - Image Utilities, Part16/18
Message-ID: <1993Mar26.202947.15113@sparky.imd.sterling.com>
X-Md4-Signature: 0ce527b864af74accede3a338ea6412b
Date: Fri, 26 Mar 1993 20:29:47 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: jwbirdsa@picarefy.picarefy.com (James W. Birdsall)
Posting-number: Volume 36, Issue 86
Archive-name: chiaro/part16
Environment: UNIX, Sun, DECstation, 3B1
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: src/comsrch.c src/gifcheck.c src/mf.h
# Wrapped by kent@sparky on Thu Mar 25 11:20:07 1993
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 16 (of 18)."'
if test -f 'src/comsrch.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/comsrch.c'\"
else
echo shar: Extracting \"'src/comsrch.c'\" \(24372 characters\)
sed "s/^X//" >'src/comsrch.c' <<'END_OF_FILE'
X/***************************************************************************
X* comsrch.C *
X* MODULE: - *
X* OS: UNIX *
X* *
X* Copyright (c) 1993 James W. Birdsall. All Rights Reserved. *
X* *
X* This file contains the code for parsing complex search strings and *
X* performing the search. *
X* *
X* $Id: comsrch.c,v 1.8 1993/03/13 02:57:12 jwbirdsa Exp $
X* *
X***************************************************************************/
X
X#include "config.h"
X
X/*
X** system includes <>
X*/
X
X#ifndef NO_STDLIB
X#include <stdlib.h>
X#endif
X#ifndef NO_STR_INC
X#ifdef STRING_PLURAL
X#include <strings.h>
X#else
X#include <string.h>
X#endif
X#endif
X#include <ctype.h>
X#include <setjmp.h>
X
X
X/*
X** custom includes ""
X*/
X
X#include "depend.h"
X
X#include "formats.h"
X#include "comsrch.h"
X
X
X/*
X** local #defines
X*/
X
X/* Token types returned by gettok(). */
X
X#define BAD_TOKEN -1
X
X#define LEFT_PAREN 0
X#define RIGHT_PAREN 1
X#define GREATER_THAN 2
X#define LESS_THAN 3
X#define EQUALITY 4
X#define GTR_EQUALS 5
X#define LESS_EQUALS 6
X#define LOGICAL_AND 7
X#define LOGICAL_OR 8
X#define END_OF_LINE 9
X#define FORMAT_ID 10
X#define NUMBER 11
X
X/* Length of stack. */
X
X#define STACK_LEN 25
X
X
X/*
X** misc: copyright strings, version macros, etc.
X*/
X
Xstatic char CONST rcsid[] = "$Id: comsrch.c,v 1.8 1993/03/13 02:57:12 jwbirdsa Exp $";
X
X
X/*
X** typedefs
X*/
X
Xtypedef struct {
X int tokentype;
X union {
X fsearch *format;
X ULONG number;
X } tokendata;
X} token;
X
X
X/*
X** global variables
X*/
X
X/*
X** static globals
X*/
X
Xint com_errorflag;
X
Xstatic ULONG s_height;
Xstatic ULONG s_width;
Xstatic ULONG s_colors;
Xstatic ULONG s_format;
Xstatic ULONG s_filelen;
X
Xstatic int stack[STACK_LEN];
Xstatic int stack_ptr;
X
Xstatic jmp_buf jumpb;
X
X
X/*
X** function prototypes
X*/
X
X#ifdef __STDC__
X# define P_(s) s
X#else
X# define P_(s) ()
X#endif
X
Xstatic char *eval P_((char *string, int level));
Xstatic token *gettok P_((char **string));
X
Xstatic VOID push P_((int x));
Xstatic int pop();
X
X#undef P_
X
X#ifdef NO_STR_INC
Xextern int strlen();
X#endif
X
X
X/*
X** functions
X*/
X
X
X/***************************************************************************
X* FUNCTION: COMCHECK *
X* *
X* DESCRIPTION: *
X* *
X* This function checks a search string to make sure all tokens are *
X* valid and in a valid order. *
X* *
X* ENTRY: *
X* *
X* searchstr - string to be checked *
X* *
X* EXIT: *
X* *
X* Returns 1 for a good string, 0 for a bad string. *
X* *
X* CONSTRAINTS/SIDE EFFECTS: *
X* *
X***************************************************************************/
Xint
X#ifdef __STDC__
Xcomcheck(char *searchstr)
X#else
Xcomcheck(searchstr)
Xchar *searchstr;
X#endif
X{
X /* Clear error flag. */
X
X com_errorflag = 0;
X
X /* Do parse with dummy values. */
X
X comsearch(1L, 1L, 1L, 0L, 0L, searchstr);
X
X /* If error flag is set, there is a problem. */
X
X return ((com_errorflag != 0) ? 0 : 1);
X} /* end of comcheck() */
X
X
X/***************************************************************************
X* FUNCTION: COMSEARCH *
X* *
X* DESCRIPTION: *
X* *
X* This function is the interface to the outside world. It sets up *
X* static global variables for the use of the parsing functions, sets *
X* up the stack, and starts the search. When the search is complete, *
X* it reads the final value off the stack and returns it. *
X* *
X* If there is an error in the pattern, a match is assumed. *
X* *
X* ENTRY: *
X* *
X* height - height of image *
X* width - width of image *
X* colors - colors in image *
X* format - format of image *
X* searchstr - the complex search string *
X* *
X* EXIT: *
X* *
X* Returns 1 on match, 0 on no match. *
X* *
X* CONSTRAINTS/SIDE EFFECTS: *
X* *
X***************************************************************************/
Xint
X#ifdef __STDC__
Xcomsearch(ULONG height, ULONG width, ULONG colors, ULONG format, ULONG filelen,
X char *searchstr)
X#else
Xcomsearch(height, width, colors, format, filelen, searchstr)
XULONG height;
XULONG width;
XULONG colors;
XULONG format;
XULONG filelen;
Xchar *searchstr;
X#endif
X{
X /* Clear error flag. */
X
X com_errorflag = 0;
X
X /* Set global variables. */
X
X s_height = height;
X s_width = width;
X s_colors = colors;
X s_format = format;
X s_filelen = filelen;
X
X /* Set up stack. */
X
X stack_ptr = STACK_LEN - 1;
X
X /* Set up for emergency return if necessary. */
X
X if (setjmp(jumpb) != 0)
X {
X /* Handle emergency return by returning 1. */
X
X com_errorflag = 1;
X return 1;
X }
X
X /* Call parser. */
X
X eval(searchstr, 0);
X
X /* There should be one and exactly one value on the stack. */
X
X if (stack_ptr != (STACK_LEN - 2))
X {
X /* Handle error by returning 1. */
X
X com_errorflag = 1;
X return 1;
X }
X
X /* Otherwise return top of stack. */
X
X return (stack[STACK_LEN - 1]);
X} /* end of comsearch() */
X
X
X/***************************************************************************
X* FUNCTION: EVAL (STATIC) *
X* *
X* DESCRIPTION: *
X* *
X* This function evaluates the search string. *
X* *
X* ENTRY: *
X* *
X* searchstr - string to be evaluated *
X* level - current level of recursion *
X* *
X* EXIT: *
X* *
X* Returns string pointer after last token evaluated. *
X* *
X* CONSTRAINTS/SIDE EFFECTS: *
X* *
X* May change contents of stack[] and value of stack_ptr. May never *
X* return if error encountered. *
X* *
X***************************************************************************/
Xstatic char *
X#ifdef __STDC__
Xeval(char *string, int level)
X#else
Xeval(string, level)
Xchar *string;
Xint level;
X#endif
X{
X token *tok;
X ULONG x, y;
X int op;
X
X /* Get first token. */
X
X tok = gettok(&string);
X
X /* Start looping. */
X
X while (tok->tokentype != END_OF_LINE)
X {
X switch (tok->tokentype)
X {
X case LEFT_PAREN:
X /* Evaluate expression to right of paren. */
X
X string = eval(string, (level + 1));
X
X /* If not level 0, return. */
X
X if (level != 0)
X {
X return string;
X }
X break;
X
X case RIGHT_PAREN:
X case END_OF_LINE:
X /* Check for nesting and length OK. */
X
X if ((0 == level) && (stack_ptr != (STACK_LEN - 1)) &&
X (END_OF_LINE == tok->tokentype))
X {
X /* Some sort of nesting error. */
X
X com_errorflag = 1;
X longjmp(jumpb, 1);
X }
X
X /* If OK, just return. */
X
X return string;
X
X case LOGICAL_AND:
X case LOGICAL_OR:
X /* Save token type. */
X
X op = tok->tokentype;
X
X /* Evaluate expression to right of operator. */
X
X string = eval(string, (level + 1));
X
X /* Pop top two values. */
X
X x = pop();
X y = pop();
X
X /* Do the operation and push the result. */
X
X push(((LOGICAL_AND == op) ? (x && y) : (x || y)));
X
X /* If not level 0, return. */
X
X if (level != 0)
X {
X return string;
X }
X break;
X
X case FORMAT_ID:
X /* Check for format match. */
X
X if ((s_format & tok->tokendata.format->value.mask) ==
X tok->tokendata.format->value.value)
X {
X /* If match, push true. */
X
X push(1);
X }
X else
X {
X /* No match, push false. */
X
X push(0);
X }
X break;
X
X case NUMBER:
X /* Save this number. */
X
X x = tok->tokendata.number;
X
X /* Get next token. */
X
X tok = gettok(&string);
X
X /* If it is not an comparison operator, error. */
X
X op = tok->tokentype;
X if ((op != LESS_THAN) && (op != GREATER_THAN) &&
X (op != EQUALITY) && (op != GTR_EQUALS) &&
X (op != LESS_EQUALS))
X {
X com_errorflag = 1;
X longjmp(jumpb, 1);
X }
X
X /* Get next token. */
X
X tok = gettok(&string);
X
X /* If it is not another number, error. */
X
X if (tok->tokentype != NUMBER)
X {
X com_errorflag = 1;
X longjmp(jumpb, 1);
X }
X
X /* Do the operation and push the result. */
X
X y = tok->tokendata.number;
X switch (op)
X {
X case LESS_THAN:
X push((x < y));
X break;
X
X case GREATER_THAN:
X push((x > y));
X break;
X
X case EQUALITY:
X push((x == y));
X break;
X
X case LESS_EQUALS:
X push((x <= y));
X break;
X
X case GTR_EQUALS:
X push((x >= y));
X break;
X
X default:
X /* Internal error. */
X
X com_errorflag = 1;
X longjmp(jumpb, 1);
X }
X break;
X
X default:
X /* Bad token. */
X
X com_errorflag = 1;
X longjmp(jumpb, 1);
X }
X
X /* Get next token and loop around. */
X
X tok = gettok(&string);
X }
X
X return string;
X} /* end of static eval() */
X
X
X/***************************************************************************
X* FUNCTION: GETTOK (STATIC) *
X* *
X* DESCRIPTION: *
X* *
X* This function extracts the next token from the string. The string *
X* pointer is advanced. *
X* *
X* ENTRY: *
X* *
X* string - pointer to string pointer *
X* *
X* EXIT: *
X* *
X* Returns pointer to token. This data is kept in static internal *
X* structure and will be destroyed by subsequent calls! *
X* *
X* CONSTRAINTS/SIDE EFFECTS: *
X* *
X***************************************************************************/
Xstatic token *
X#ifdef __STDC__
Xgettok(char **string)
X#else
Xgettok(string)
Xchar **string;
X#endif
X{
X static token storage;
X
X char buffer[15];
X int bufind;
X int loop;
X int length;
X int maxlen;
X int maxmatch;
X
X /* Switch by first character of token. */
X
X switch ((*string)[0])
X {
X case '(':
X storage.tokentype = LEFT_PAREN;
X (*string)++;
X break;
X
X case ')':
X storage.tokentype = RIGHT_PAREN;
X (*string)++;
X break;
X
X case '=':
X storage.tokentype = EQUALITY;
X (*string)++;
X break;
X
X#ifdef DOS_COMSRCH
X case '+':
X#else
X case '&':
X#endif
X storage.tokentype = LOGICAL_AND;
X (*string)++;
X break;
X
X#ifdef DOS_COMSRCH
X case ',':
X#else
X case '|':
X#endif
X storage.tokentype = LOGICAL_OR;
X (*string)++;
X break;
X
X case '\0':
X storage.tokentype = END_OF_LINE;
X break;
X
X#ifdef DOS_COMSRCH
X case '}':
X#else
X case '>':
X#endif
X if ('=' == (*string)[1])
X {
X storage.tokentype = GTR_EQUALS;
X *string += 2;
X break;
X }
X storage.tokentype = GREATER_THAN;
X (*string)++;
X break;
X
X#ifdef DOS_COMSRCH
X case '{':
X#else
X case '<':
X#endif
X if ('=' == (*string)[1])
X {
X storage.tokentype = LESS_EQUALS;
X *string += 2;
X break;
X }
X storage.tokentype = LESS_THAN;
X (*string)++;
X break;
X
X default:
X if ((('H' == (*string)[0]) || ('W' == (*string)[0]) ||
X ('C' == (*string)[0]) || ('F' == (*string)[0])) &&
X (isalnum((*string)[1]) == 0))
X {
X /*
X ** Token starts with H, W, C, or F, and the next chararcter
X ** is not a letter or number, so the token can't be a format.
X ** It must be one of the symbolic constants.
X */
X
X switch ((*string)[0])
X {
X case 'H':
X storage.tokentype = NUMBER;
X storage.tokendata.number = s_height;
X (*string)++;
X break;
X
X case 'W':
X storage.tokentype = NUMBER;
X storage.tokendata.number = s_width;
X (*string)++;
X break;
X
X case 'C':
X storage.tokentype = NUMBER;
X storage.tokendata.number = s_colors;
X (*string)++;
X break;
X
X case 'F':
X storage.tokentype = NUMBER;
X storage.tokendata.number = s_filelen;
X (*string)++;
X break;
X }
X }
X else if (isdigit(**string))
X {
X /* Is a number -- collect in buffer. */
X
X for (bufind = 0; isdigit(buffer[bufind] = (*string)[0]);
X (*string)++, bufind++) ;
X
X /* Convert. */
X
X buffer[bufind] = '\0';
X storage.tokendata.number = (ULONG) atol(buffer);
X
X /* Finish. */
X
X storage.tokentype = NUMBER;
X break;
X }
X else
X {
X /*
X ** Is a format or nothing. Search through table of formats
X ** for specified type, looking for longest match.
X */
X
X maxlen = 0;
X for (loop = 0; formatsearch[loop].name[0] != '\0'; loop++)
X {
X /* Check against table of strings. */
X
X length = strlen(formatsearch[loop].name);
X if (strnicmp(formatsearch[loop].name, *string, length))
X {
X continue;
X }
X
X /* String matched in order to get here. */
X
X if (length > maxlen)
X {
X /* If this match longer than previous, use this one. */
X maxlen = length;
X maxmatch = loop;
X }
X }
X
X /* Was a match found? */
X
X if (0 == maxlen)
X {
X /* No. Is bad token. */
X
X storage.tokentype = BAD_TOKEN;
X break;
X }
X
X /* Is format. */
X
X storage.tokentype = FORMAT_ID;
X storage.tokendata.format = &(formatsearch[maxmatch]);
X *string += maxlen;
X break;
X }
X }
X
X return &storage;
X} /* end of static gettok() */
X
X
X/***************************************************************************
X* FUNCTION: PUSH (STATIC) *
X* *
X* DESCRIPTION: *
X* *
X* Pushes a value on the stack. If stack overflow, performs an *
X* emergency return. *
X* *
X* ENTRY: *
X* *
X* x - value to push on stack *
X* *
X* EXIT: *
X* *
X* Returns nothing. *
X* *
X* CONSTRAINTS/SIDE EFFECTS: *
X* *
X* Alters contents of stack[] and value of stack_ptr. May never *
X* return. *
X* *
X***************************************************************************/
Xstatic VOID
X#ifdef __STDC__
Xpush(int x)
X#else
Xpush(x)
Xint x;
X#endif
X{
X /* Put value on stack. */
X
X stack[stack_ptr--] = x;
X
X /* If stack overflow, emergency return. */
X
X if (stack_ptr < 0)
X {
X com_errorflag = 1;
X longjmp(jumpb, 1);
X }
X
X return;
X} /* end of static push() */
X
X
X/***************************************************************************
X* FUNCTION: POP (STATIC) *
X* *
X* DESCRIPTION: *
X* *
X* Pops a value from the stack. If stack underflow, performs an *
X* emergency return. *
X* *
X* ENTRY: *
X* *
X* void *
X* *
X* EXIT: *
X* *
X* Returns the value popped from the stack. *
X* *
X* CONSTRAINTS/SIDE EFFECTS: *
X* *
X* Alters contents of stack[] and value of stack_ptr. May never *
X* return. *
X* *
X***************************************************************************/
Xstatic int
X#ifdef __STDC__
Xpop(VOID)
X#else
Xpop()
X#endif
X{
X /* Check for stack underflow. */
X
X if ((STACK_LEN - 1) == stack_ptr)
X {
X /* Stack is going to underflow on this pop, do emergency return. */
X
X com_errorflag = 1;
X longjmp(jumpb, 1);
X }
X
X /* Else return value from stack. */
X
X return (stack[++stack_ptr]);
X} /* end of static pop() */
X
END_OF_FILE
if test 24372 -ne `wc -c <'src/comsrch.c'`; then
echo shar: \"'src/comsrch.c'\" unpacked with wrong size!
fi
# end of 'src/comsrch.c'
fi
if test -f 'src/gifcheck.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/gifcheck.c'\"
else
echo shar: Extracting \"'src/gifcheck.c'\" \(25104 characters\)
sed "s/^X//" >'src/gifcheck.c' <<'END_OF_FILE'
X/***************************************************************************
X* GIFCHECK.C *
X* MODULE: - *
X* OS: UNIX *
X* *
X* Copyright (c) 1993 James W. Birdsall. All Rights Reserved. *
X* *
X* The Graphics Interchange Format(c) is the Copyright property of *
X* CompuServe Incorporated. GIF(sm) is a Service Mark property of *
X* CompuServe Incorporated. *
X* *
X* GIF and "Graphic Interchange Format" are trademarks (tm) of *
X* CompuServe, Inc., an H&R Block company. *
X* *
X* $Id: gifcheck.c,v 1.8 1993/03/08 00:22:02 jwbirdsa Exp $
X* *
X***************************************************************************/
X
X#include "config.h"
X
X/*
X** system includes <>
X*/
X
X#include <stdio.h>
X#include <ctype.h>
X#ifndef NO_STDLIB
X#include <stdlib.h>
X#endif
X#ifndef NO_MALLOCHDR
X#include <malloc.h>
X#endif
X#ifndef NO_STR_INC
X#ifdef STRING_PLURAL
X#include <strings.h>
X#else
X#include <string.h>
X#endif
X#endif
X
X
X/*
X** custom includes ""
X*/
X
X#include "depend.h"
X
X#include "fb.h"
X
X#include "formats.h"
X#include "gif.h"
X#include "gld.h"
X
X#include "colors.h"
X
X#include "gifcheck.h"
X#include "blocproc.h"
X
X#include "stdinarg.h"
X
X#include "patchlevel.h"
X
X
X/*
X** local #defines
X*/
X
X#define FB_TABLESIZE 5
X#ifdef SMALL_MEM
X#define FB_BUFSIZE 4096
X#else
X#define FB_BUFSIZE 30000
X#endif
X
X#define TBUFSIZ 15
X
X
X/*
X** misc: copyright strings, version macros, etc.
X*/
X
Xstatic char CONST copyright[] = "Copyright (c) 1992 James W. Birdsall. All Rights Reserved";
Xstatic char CONST rcsid[] = "$Id: gifcheck.c,v 1.8 1993/03/08 00:22:02 jwbirdsa Exp $";
X
X#define VERS "1.0"
X
X
X/*
X** typedefs
X*/
X
X/*
X** global variables
X*/
X
X/* Default: allow leading junk. */
X
Xint lead = 1;
X
X/* Default: do decompression. */
X
Xint decomp = 1;
X
X/* Default: don't dump color tables. */
X
Xint do_colordump = 0;
X
X/* Default: display FASCINATING and above, abort on VIOLATION and above. */
X
Xint dlevel = DLEVEL_FASCINATING;
Xint elevel = ELEVEL_VIOLATION;
X
X/* Default: terse displays. */
X
Xint verbose = 0;
X
X/* Default: don't do hex dump of PTEs, comments, app & generic extensions. */
X
Xint do_hexdump = 0;
X
X/* Default: display progress indicator, if compiled in. */
X
X#ifdef PROGRESS_IND
Xint prog_ind = 1;
X#endif
X
X/* File handles for standard and error output. */
X
XFILE *outstr = stdout;
XFILE *outerr = stdout;
X
X/* Global scratch space. */
X
Xchar scratch[132];
X
X
X/* Global color table. */
X
Xextern RGB_TRIPLET *gct;
X
X/* Last state. */
X
Xextern int laststate;
X
X
X/*
X** static globals
X*/
X
X/*
X** function prototypes
X*/
X
X#ifdef __STDC__
X# define P_(s) s
X#else
X# define P_(s) ()
X#endif
X
Xstatic int check P_((char *filename));
X
Xstatic VOID usage();
X
X#undef P_
X
X#ifdef NO_STR_INC
X#ifndef NO_STRDUP
Xextern char *strdup();
X#endif
X#endif
X
X
X/*
X** functions
X*/
X
X
X/***************************************************************************
X * FUNCTION MAIN *
X ***************************************************************************/
X#ifdef __STDC__
Xmain(int argc, char *argv[])
X#else
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X#endif
X{
X int loop, loop2;
X int onlyflags = 1;
X int argcc;
X char **argvv;
X char **namelist;
X int stdinkey = 1; /* Nonzero = stdin is keyboard, zero = redirected. */
X int errorlevel;
X int temp;
X
X /* Search for option and parse if found. */
X
X for(loop = 1; loop < argc; loop++)
X {
X if ('-' == argv[loop][0])
X {
X switch (argv[loop][1])
X {
X /* Disable decompression to increase speed. */
X case 'f':
X decomp = 0;
X break;
X
X /* Batch mode option. */
X case 'b':
X if ((outstr = fopen(NULL_DEVICE, "w")) == (FILE *) NULL)
X {
X fprintf(stderr, "ERROR: Cannot open %s\n", NULL_DEVICE);
X exit(EXIT_ERROR);
X }
X outerr = outstr;
X#ifdef PROGRESS_IND
X /* Turn off progress indicator automatically. */
X prog_ind = 0;
X#endif
X break;
X
X /* Disable handling of leading junk. */
X case 'l':
X lead = 0;
X break;
X
X /* Redirect errors to stderr. */
X case 'r':
X outerr = stderr;
X break;
X
X /* Dump color tables. */
X case 'c':
X do_colordump = 1;
X break;
X
X /* Do hex dumps of PTEs, comments. */
X case 'H':
X do_hexdump = 1;
X break;
X
X#ifdef PROGRESS_IND
X /* Turn off progress indicator. */
X case 'p':
X prog_ind = 0;
X break;
X#endif
X
X /* Verbose option. */
X case 'v':
X verbose = 1;
X break;
X
X /* Set warning display level. */
X case 'd':
X temp = atoi(argv[loop] + 2);
X if ((temp < 0) || (temp > DLEVEL_NITPICK))
X {
X usage();
X }
X dlevel = temp;
X break;
X
X /* Set warning exit level. */
X case 'e':
X temp = atoi(argv[loop] + 2);
X if ((temp < 0) || (temp > ELEVEL_FASCINATING))
X {
X usage();
X }
X elevel = temp;
X break;
X
X /* Take filenames from stdin. */
X case '-':
X stdinkey = 0;
X break;
X
X /* Help option. */
X case 'h':
X /* Unknown option. */
X default:
X usage();
X break;
X }
X }
X else
X {
X /*
X ** onlyflags == 1 when the command line contains only options.
X ** If this clause is executed, means there is at least one arg
X ** which is not an option and therefore is a target.
X */
X
X onlyflags = 0;
X }
X }
X
X /* If no target(s) specified and stdin not redirected, error. */
X
X if ((onlyflags != 0) && (stdinkey != 0))
X {
X usage();
X }
X
X /* Initialize file buffering package. */
X
X if (fb_init(FB_TABLESIZE, FB_BUFSIZE) != 0)
X {
X fprintf(outerr, "%s\n", fb_errstring(fb_error));
X exit(EXIT_ERROR);
X }
X
X /* Check for stdin redirection -- load target from stdin if redirected. */
X
X if (stdinkey != 0)
X {
X argcc = argc;
X argvv = argv;
X }
X else
X {
X argvv = stdinload(&argcc);
X argvv[0] = argv[0];
X }
X
X /* Loop through targets, processing. */
X
X for(loop = 1; loop < argcc; loop++)
X {
X if (argvv[loop][0] != '-')
X {
X /* Extract an argument from the command line and expand it. */
X
X if ((namelist = scand(argvv[loop])) == NULL)
X {
X fprintf(outerr, "ERROR: bad target %s\n", argvv[loop]);
X continue;
X }
X else if (NULL == namelist[0])
X {
X fprintf(outerr, "WARNING: no files matching %s found.\n",
X argvv[loop]);
X continue;
X }
X
X /* Check each file. */
X
X for(loop2 = 0; namelist[loop2]; loop2++)
X {
X fprintf(outstr, "\nProcessing %s...\n", namelist[loop2]);
X errorlevel = check(namelist[loop2]);
X if (gct != (RGB_TRIPLET *) NULL)
X {
X free(gct);
X gct = (RGB_TRIPLET *) NULL;
X }
X }
X
X /* Cleanup. */
X
X for(loop2 = 0; namelist[loop2]; loop2++)
X {
X free(namelist[loop2]);
X }
X free(namelist);
X if (0 == stdinkey)
X {
X free(argvv[loop]);
X }
X }
X }
X
X /* Cleanup. */
X
X if (0 == stdinkey)
X {
X free(argvv);
X }
X
X exit(errorlevel);
X} /* end of main() */
X
X
X/***************************************************************************
X* FUNCTION: errxlate *
X* *
X* DESCRIPTION: *
X* *
X* Translates an error code into a string. *
X* *
X* ENTRY: *
X* *
X* errcode - code to be translated *
X* *
X* EXIT: *
X* *
X* Returns a pointer to the appropriate string. *
X* *
X* CONSTRAINTS/SIDE EFFECTS: *
X* *
X***************************************************************************/
Xchar *
X#ifdef __STDC__
Xerrxlate(ULONG errcode)
X#else
Xerrxlate(errcode)
XULONG errcode;
X#endif
X{
X char *errstring;
X char *sever;
X
X /* Determine severity of error. */
X
X switch (SEVERITY(errcode))
X {
X case SEVERITY(ST_SUCCESS):
X sever = "SUCCESS";
X break;
X
X case SEVERITY(ST_WARNING):
X sever = "WARNING";
X break;
X
X case SEVERITY(ST_ERROR):
X sever = "ERROR";
X break;
X
X case SEVERITY(ST_FATAL):
X default:
X sever = "FATAL";
X break;
X }
X
X /* Get error string from module. */
X
X switch (MODULE(errcode))
X {
X case MODULE(GIF_MODULE):
X errstring = gif_errstring(errcode);
X break;
X
X case MODULE(FB_MODULE):
X errstring = fb_errstring(errcode);
X break;
X
X case MODULE(GLD_MODULE):
X errstring = gld_errstring(errcode);
X break;
X
X default:
X errstring = NULL;
X break;
X }
X
X /* Composite strings. */
X
X if (errstring != NULL)
X {
X sprintf(scratch, "%s: %s", sever, errstring);
X }
X else
X {
X /* Error not recognized by any module. */
X
X sprintf(scratch, "%s: %08lX.", sever, errcode);
X }
X
X return scratch;
X} /* end of errxlate() */
X
X
X/***************************************************************************
X* FUNCTION: check STATIC *
X* *
X* DESCRIPTION: *
X* *
X* This function verifies the named file, if necessary. *
X* *
X* ENTRY: *
X* *
X* filename - name of file to be verified. May include drive and/or *
X* path. *
X* *
X* EXIT: *
X* *
X* Returns EXIT_*, depending. *
X* *
X* CONSTRAINTS/SIDE EFFECTS: *
X* *
X***************************************************************************/
Xstatic int
X#ifdef __STDC__
Xcheck(char *filename)
X#else
Xcheck(filename)
Xchar *filename;
X#endif
X{
X FILE *origfile;
X FB *infile;
X ULONG status;
X long size;
X int mskip = 0;
X ULONG skip;
X long stop;
X
X int images = 1;
X int gens = 1;
X int ptes = 1;
X int gces = 1;
X int comments = 1;
X int apps = 1;
X
X GIF_LSD lsd;
X int blocktype;
X int extype;
X GIF_IMD imd;
X
X /* Setup. */
X
X gct = (RGB_TRIPLET *) NULL;
X laststate = STATE_BEGIN;
X
X /* Open GIF and perform other startup functions. */
X
X if ((origfile = fopen(filename, FOPEN_READ_BINARY)) == (FILE *) NULL)
X {
X fprintf(outerr, "ERROR: Cannot open file %s\n", filename);
X return EXIT_ERROR;
X }
X
X /* Get the size by forwarding to the end and reading offset. */
X
X if (fseek(origfile, 0L, SEEK_END) == -1)
X {
X fprintf(outerr, "ERROR: Error seeking in %s\n", filename);
X fclose(origfile);
X return EXIT_ERROR;
X }
X size = ftell(origfile);
X
X /* Get GIF logical screen descriptor. */
X
X if (0 == lead)
X {
X if ((status = gif_lsdget(origfile, &lsd)) != ST_SUCCESS)
X {
X fprintf(outerr, "%s\n", errxlate(status));
X fclose(origfile);
X switch (ERRSEV(status))
X {
X case ERRSEV(GIF_NOTGIF_E):
X return EXIT_NOTGIF;
X
X case ERRSEV(GIF_UNEOF_E):
X return EXIT_UNEOF;
X
X default:
X return EXIT_ERROR;
X }
X }
X
X /* Attach buffering to GIF file. */
X
X infile = fb_retrofit(origfile, 'r');
X if (fb_error != ST_SUCCESS)
X {
X fprintf(outerr, "%s\n", errxlate(fb_error));
X fclose(origfile);
X return EXIT_ERROR;
X }
X }
X else
X {
X /* Attach buffering to original GIF file. */
X
X infile = fb_retrofit(origfile, 'r');
X if (fb_error != ST_SUCCESS)
X {
X fprintf(outerr, "%s\n", errxlate(fb_error));
X fclose(origfile);
X return EXIT_ERROR;
X }
X
X /* Search for potentially buried LSD. */
X
X if ((status = gif_searchlsd(infile, &lsd, &skip)) != ST_SUCCESS)
X {
X fprintf(outerr, "%s\n", errxlate(status));
X fb_close(infile);
X switch (ERRSEV(status))
X {
X case ERRSEV(GIF_NOTGIF_E):
X case ERRSEV(GIF_UNEOF_E):
X return EXIT_NOTGIF;
X
X default:
X return EXIT_ERROR;
X }
X }
X if (skip != 0)
X {
X fprintf(outstr, "STRIP: Skipped %lu leading junk bytes.\n", skip);
X mskip = 1;
X }
X }
X
X /* Print out info from logical screen descriptor. */
X
X if ((status = global_printout(infile, filename, &lsd, size)) != EXIT_OK)
X {
X return (int) status;
X }
X
X /* Loop through data blocks. */
X
X blocktype = 0;
X while (blocktype != GIF_TERMINATOR)
X {
X /* Find next block. */
X
X if ((status = gif_findnext(infile, &blocktype, &skip, &extype)) !=
X ST_SUCCESS)
X {
X fprintf(outerr, "%s\n", errxlate(status));
X fb_close(infile);
X return ((GIF_UNEOF_E == status) ? EXIT_UNEOF : EXIT_ERROR);
X }
X
X /* If skipped characters, FYI. */
X
X if (skip != 0)
X {
X if (dlevel >= DLEVEL_VIOLATION)
X {
X fprintf(outstr,
X "VIOLATION: %lu garbage characters found between blocks\n",
X skip);
X }
X if (elevel >= ELEVEL_VIOLATION)
X {
X fb_close(infile);
X return EXIT_NOTGIF;
X }
X }
X
X /* Process by type of block. */
X
X switch (blocktype)
X {
X case GIF_IMAGE:
X fprintf(outstr, "IMAGE %d:\n", images);
X
X /* Check ordering. */
X
X if ((status = follow(STATE_IMAGE)) != EXIT_OK)
X {
X fb_close(infile);
X return (int) status;
X }
X
X /* Get image descriptor. */
X
X if ((status = gif_imdget(infile, &imd)) != ST_SUCCESS)
X {
X fprintf(outerr, "%s\n", errxlate(status));
X fb_close(infile);
X return ((GIF_UNEOF_E == status) ? EXIT_UNEOF : EXIT_ERROR);
X }
X
X /* Print out information from image descriptor. */
X
X status = image_printout(infile, &imd, images++, lsd.version,
X lsd.gct_size);
X if (status != EXIT_OK)
X {
X return (int) status;
X }
X
X break;
X
X case GIF_EXTBLOCK:
X /* Print some info. */
X
X if (GIF_89A == lsd.version)
X {
X switch (extype)
X {
X case GIF_EXT_PLAIN_TEXT:
X status = pte_printout(infile, ptes++);
X break;
X
X case GIF_EXT_GRAPHIC_CONTROL:
X status = gce_printout(infile, gces++);
X break;
X
X case GIF_EXT_COMMENT:
X status = comment_printout(infile, comments++);
X break;
X
X case GIF_EXT_APPLICATION:
X status = app_printout(infile, apps++);
X break;
X
X default:
X status = genext_printout(infile, extype, gens++);
X break;
X }
X }
X else
X {
X status = genext_printout(infile, extype, gens++);
X }
X if (status != EXIT_OK)
X {
X /* No need to close infile -- done by *_printout(). */
X
X return (int) status;
X }
X
X break;
X
X case GIF_TERMINATOR:
X fprintf(outstr, "GIF TERMINATOR\n");
X if ((status = follow(STATE_TERM)) != EXIT_OK)
X {
X fb_close(infile);
X return (int) status;
X }
X break;
X
X default:
X fprintf(outerr, "FATAL ERROR: Internal error.\n");
X break;
X
X } /* End of switch (blocktype). */
X } /* End of while (blocktype != GIF_TERMINATOR). */
X
X /* Read all good data from file, clean up. */
X
X stop = fb_tell(infile);
X if (fb_error != 0)
X {
X fprintf(outerr, "%s\n", errxlate(fb_error));
X fb_close(infile);
X return EXIT_ERROR;
X }
X if ((status = fb_close(infile)) != ST_SUCCESS)
X {
X fprintf(outerr, "%s\n", errxlate(status));
X return EXIT_ERROR;
X }
X
X /* extype set to nonzero if trailing garbage detected. */
X if (extype != 0)
X {
X fprintf(outstr, "STRIP: %ld trailing junk bytes.\n", (size - stop + 1));
X }
X
X /* All done, return OK. */
X
X if (mskip != 0)
X {
X return EXIT_STRIPM;
X }
X else if (stop != size)
X {
X return EXIT_STRIP;
X }
X
X return EXIT_OK;
X} /* end of static check() */
X
X
X/***************************************************************************
X* FUNCTION: usage STATIC *
X* *
X* DESCRIPTION: *
X* *
X* Prints out usage message. *
X* *
X* ENTRY: *
X* *
X* None. *
X* *
X* EXIT: *
X* *
X* Never returns. *
X* *
X* CONSTRAINTS/SIDE EFFECTS: *
X* *
X* Exit()s with errorlevel EXIT_ERROR. *
X* *
X***************************************************************************/
Xstatic VOID
Xusage()
X{
X fprintf(outstr, "\n");
X fprintf(outstr,
X "GIFCHECK version %s, patchlevel %d by James W. Birdsall.\n",
X VERS, PATCHLEVEL);
X fprintf(outstr, " Verifies format and validity of GIF files.\n");
X fprintf(outstr, " usage: gifcheck [options] target [target ...]\n");
X fprintf(outstr, " target filename or directory. If a directory, all files in that\n");
X fprintf(outstr, " directory will be processed. If no targets are given,\n");
X fprintf(outstr, " this usage message is displayed.\n");
X
X fprintf(outstr, " -v VERBOSE: turns on verbose output.\n");
X fprintf(outstr, " -H HEX DUMP: switches from ASCII to HEX dump for certain blocks.\n");
X fprintf(outstr, " -c COLOR DUMP: dumps raw RGB values from all colormaps.\n");
X#ifdef PROGRESS_IND
X fprintf(outstr, " -p Turn off progress indicator (automatically turned off by -b).\n");
X#endif
X
X fprintf(outstr, " -dn SET DISPLAY WARNING LEVEL: 0 for anomalies and violations\n");
X fprintf(outstr, " only, 1 (default) for those and fascinatings, 2 for all.\n");
X fprintf(outstr, " -en SET EXIT WARNING LEVEL: 0 for anomalies only, 1 (default) for\n");
X fprintf(outstr, " anomalies and violations, 2 for anomalies, violations, and\n");
X fprintf(outstr, " fascinatings.\n");
X
X fprintf(outstr, " -b BATCH: suppresses all console output. Should be first on the\n");
X fprintf(outstr, " line. Returns 0 if OK, 1 if a non-GIF file was found, 2 if\n");
X fprintf(outstr, " unexpected EOF in a GIF file, 3 on other error, 4 if the\n");
X fprintf(outstr, " GIF is OK but needs to be stripped, and 5 if the GIF is OK\n");
X fprintf(outstr, " but needs to be stripped with the -m option.\n");
X fprintf(outstr, " -r Sends error messages to stderr instead of stdout.\n");
X fprintf(outstr, " -- Take targets from stdin. For use with -f option of CHILS.\n");
X fprintf(outstr, " Targets must be separated by newlines. Directories are\n");
X fprintf(outstr, " expanded but wildcards are not. Command-line targets are\n");
X fprintf(outstr, " ignored if this option is given.\n");
X fprintf(outstr, " -l Disables checking for leading junk characters (from a Mac,\n");
X fprintf(outstr, " for example).\n");
X
X fprintf(outstr, " -f FAST: disables decompression. Only block formatting is\n");
X fprintf(outstr, " checked.\n");
X fprintf(outstr, " -h HELP: Prints this message.\n");
X
X fprintf(outstr, "\n");
X fprintf(outstr, " Options may not be combined.\n");
X fprintf(outstr, "\n");
X
X exit(EXIT_ERROR);
X} /* end of static usage() */
X
END_OF_FILE
if test 25104 -ne `wc -c <'src/gifcheck.c'`; then
echo shar: \"'src/gifcheck.c'\" unpacked with wrong size!
fi
# end of 'src/gifcheck.c'
fi
if test -f 'src/mf.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/mf.h'\"
else
echo shar: Extracting \"'src/mf.h'\" \(2483 characters\)
sed "s/^X//" >'src/mf.h' <<'END_OF_FILE'
X/***************************************************************************
X* MF.H *
X* HEADER FOR MF (MemFile) MODULE *
X* OS: UNIX *
X* *
X* Copyright (c) 1993 by James W. Birdsall, all rights reserved. *
X* *
X* $Id: mf.h,v 1.5 1993/02/10 01:31:18 jwbirdsa Exp $
X* *
X* This file specifies the external interface to the memfile module. *
X* *
X***************************************************************************/
X
X#ifndef DEPEND_H
X **** ERROR **** MUST INCLUDE DEPEND.H BEFORE MF.H
X#endif
X
X#ifndef MF_H
X
X#define MF_H
X
X/*
X** system includes <>
X*/
X
X/*
X** custom includes ""
X*/
X
X#include "status.h"
X
X
X/*
X** #defines
X*/
X
X/* miscellaneous defines */
X
X#define USE_CONMEM 0x0001
X#define USE_DISKMEM 0x0008
X
X#define USE_MASK (USE_CONMEM | USE_DISKMEM)
X
X/* error/status defines */
X
X#define MF_EOF_W MKERR(1, MF_MODULE, ST_WARNING)
X
X#define MF_REOPEN_E MKERR(1, MF_MODULE, ST_ERROR)
X#define MF_EMSERROR_E MKERR(2, MF_MODULE, ST_ERROR)
X#define MF_XMSERROR_E MKERR(3, MF_MODULE, ST_ERROR)
X#define MF_DISKERROR_E MKERR(4, MF_MODULE, ST_ERROR)
X#define MF_NOSPACE_E MKERR(5, MF_MODULE, ST_ERROR)
X#define MF_NOTOPEN_E MKERR(6, MF_MODULE, ST_ERROR)
X#define MF_MALLOC_E MKERR(7, MF_MODULE, ST_ERROR)
X#define MF_UMBERROR_E MKERR(8, MF_MODULE, ST_ERROR)
X
X#define MF_BUG_F MKERR(1, MF_MODULE, ST_FATAL)
X#define MF_OVERFLOW_F MKERR(2, MF_MODULE, ST_FATAL)
X
X
X/*
X** misc: copyright strings, version macros, etc.
X*/
X
Xstatic char CONST RCSmf[] = "$Id: mf.h,v 1.5 1993/02/10 01:31:18 jwbirdsa Exp $";
X
X
X/*
X** typedefs
X*/
X
X/*
X** global variables
X*/
X
Xextern int mf_locked;
X
X
X/*
X** function prototypes
X*/
X
X#ifdef __STDC__
X# define P_(s) s
X#else
X# define P_(s) ()
X#endif
X
XULONG mf_open P_((unsigned int flags, ULONG maxsize, char *tpath));
XULONG mf_write P_((UCHAR *buffer, unsigned int length));
XULONG mf_reset();
XULONG mf_read P_((UCHAR *buffer, unsigned int length, unsigned int *lread));
XULONG mf_close();
X
Xchar *mf_errstring P_((ULONG errcode));
X
X#undef P_
X
X#endif /* MF_H */
X
END_OF_FILE
if test 2483 -ne `wc -c <'src/mf.h'`; then
echo shar: \"'src/mf.h'\" unpacked with wrong size!
fi
# end of 'src/mf.h'
fi
echo shar: End of archive 16 \(of 18\).
cp /dev/null ark16isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 18 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...