/* A *VERY SIMPLE* spelling checker to check tex sources */
/* This was my first experiment with flex.               */
/* This is just to be used as an installation test!!!    */

#include "splib.h"
NODE *dawg;
INDEX edges;

#define FLEX_COMPRESSED
/* A lexical scanner generated by flex */

/* scanner skeleton version:
 * $Header: rcs.c.texcheck 1.1 91/03/23 17:57:06 gtoal Exp Locker: gtoal $
 */

#include <stdio.h>

#define FLEX_SCANNER

/* amount of stuff to slurp up with each read */
#ifndef YY_READ_BUF_SIZE
#ifdef  LIM64K
#define YY_READ_BUF_SIZE 1024
#else
#define YY_READ_BUF_SIZE 8192
#endif
#endif

#ifndef YY_BUF_SIZE
#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of input buffer */
#endif

/* returned upon end-of-file */
#define YY_END_TOK 0

/* copy whatever the last rule matched to the standard output */

#define ECHO fputs( yytext, yyout )

/* gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
 * is returned in "result".
 */
#define YY_INPUT(buf,result,max_size) \
        result = fread( buf, 1, max_size, yyin ); \
        if ( ferror(yyin) ) \
            YY_FATAL_ERROR( "fread() in flex scanner failed" );

#define YY_NULL 0
#define yyterminate() return ( YY_NULL )

/* report a fatal error */
#define YY_FATAL_ERROR(msg) \
        { \
        fputs( msg, stderr ); \
        putc( '\n', stderr ); \
        exit( 1 ); \
        }

/* default yywrap function - always treat EOF as an EOF */
#define yywrap() 1

/* enter a start condition.  This macro really ought to take a parameter,
 * but we do it the disgusting crufty way forced on us by the ()-less
 * definition of BEGIN
 */
#define BEGIN yy_start = 1 + 2 *

/* action number for EOF rule of a given start state */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)

/* special action meaning "start processing a new file" */
#define YY_NEW_FILE goto new_file

/* default declaration of generated scanner - a define so the user can
 * easily add parameters
 */
#ifdef __STDC__
#define YY_DECL int yylex( void )
#else
#define YY_DECL int yylex()
#endif

/* code executed at the end of each rule */
#define YY_BREAK break;

#define YY_END_OF_BUFFER_CHAR 0

/* done after the current pattern has been matched and before the
 * corresponding action - sets up yytext
 */
#define YY_DO_BEFORE_ACTION \
        yytext = yy_bp; \
        yy_hold_char = *yy_cp; \
        *yy_cp = '\0'; \
        yy_c_buf_p = yy_cp;

/* returns the length of the matched text */
#define yyleng (yy_cp - yy_bp)

#define EOB_ACT_RESTART_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2

/* return all but the first 'n' matched characters back to the input stream */
#define yyless(n) \
        { \
        *yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \
        yy_c_buf_p = yy_cp = yy_bp + n; \
        YY_DO_BEFORE_ACTION; /* set up yytext again */ \
        }

#define unput(c) yyunput( c, yy_bp )

#define YY_USER_ACTION

FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
char *yytext;

#ifndef __STDC__
#define const
#endif

# line 1 "l.texread"
#define INITIAL 0
# line 2 "l.texread"
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

#define EOFTOK 0

#define WHITESPACE 256
#define ESCAPE 257
#define STYLE 258
#define NEWLINE 259
#define WORD 260
#define COMMENT 261

int yylex(void);

static int ignore;
static int cur_line = 1, cur_col = 1; /* 'real-world' conventions */

void spellcheck(char *word, int line, int col, char *fileinf) {
  char *p = word+strlen(word)-1;
  while ((*p == '\'') || (*p == '-')) *p-- = '\0';
  if (!dawg_check(dawg, word)) printf("%sLine %d, Col %d: %s\n", fileinf, line, col, word);
}

int main(int argc, char **argv)
{
  char fname[256];
  int token;

  if (argc == 2) {
    if (freopen(argv[1], "r", stdin) == NULL) {
      fprintf(stderr, "texread: cannot open input file %s\n", argv[1]);
      exit(0);
    }
    sprintf(fname, "\"%s\", ", argv[1]);
  } else {
    *fname = '\0';
  }

  dawg_init("", &dawg, &edges);

  ignore = (0!=0);
  while ((token = yylex()) != 0) {
    if (token == COMMENT) ignore = (0==0);
    else if (token == NEWLINE) {
      ignore = (0!=0);
      cur_line += 1; cur_col = 0;
    } else if (token == WORD) {
      if (!ignore) spellcheck(yytext, cur_line, cur_col, fname);
    }
    cur_col += strlen(yytext);
  }
}
# line 53 "l.texread"
#define YY_END_OF_BUFFER 13
typedef int yy_state_type;
static const short int yy_accept[41] =
    {   0,
        0,    0,   13,   11,   10,   11,   11,   11,   11,   11,
       11,   11,    1,    9,    2,    0,    0,    0,    0,    0,
        0,    0,    0,    3,    0,    0,    1,    1,    0,    0,
        8,    4,    5,    6,    7,    0,    0,    1,    1,    0
    } ;

static const char yy_ec[128] =
    {   0,
        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
        1,    4,    1,    5,    1,    1,    6,    1,    7,    1,
        1,    1,    1,    2,    8,    1,    1,    9,   10,   11,
       12,   13,   13,   13,   13,   13,   13,    1,    1,    1,
        1,    1,    1,    5,   14,   14,   14,   14,   14,   14,
       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
       15,   16,   17,    1,    1,    1,   14,   14,   14,   18,

       19,   14,   14,   20,   14,   14,   14,   14,   21,   22,
       14,   23,   14,   24,   25,   26,   14,   14,   14,   27,
       14,   14,   28,    5,   29,    1,    1
    } ;

static const char yy_meta[30] =
    {   0,
        1,    2,    1,    3,    1,    4,    5,    5,    1,    1,
        1,    1,    1,    6,    7,    5,    1,    6,    6,    6,
        6,    6,    6,    6,    6,    6,    6,    7,    1
    } ;

static const short int yy_base[46] =
    {   0,
        0,    0,   86,   79,   73,   70,   24,   50,   52,   49,
       46,   32,   27,   99,   65,   63,   23,   47,   40,   39,
       45,   44,   41,   33,   44,   51,   42,   49,    0,    0,
       99,   99,   99,   99,   99,   41,   27,   39,    4,   99,
       74,   77,   81,   87,   92
    } ;

static const short int yy_def[46] =
    {   0,
       40,    1,   40,   40,   40,   41,   40,    7,    7,    7,
        7,   42,   43,   40,   41,    7,   40,   40,   40,   40,
       40,   40,   40,   42,   24,   40,   40,   43,   44,   45,
       40,   40,   40,   40,   40,   44,   45,   40,   40,    0,
       40,   40,   40,   40,   40
    } ;

static const short int yy_nxt[129] =
    {   0,
        4,    4,    5,    4,    6,    4,    4,    4,    7,    8,
        9,   10,   11,   12,    4,   13,    4,   12,   12,   12,
       12,   12,   12,   12,   12,   12,   12,    4,    4,   14,
       27,   30,   16,   16,   16,   16,   16,   14,   40,   25,
       25,   29,   17,   31,   18,   27,   19,   26,   26,   31,
       40,   40,   27,   29,   30,   39,   29,   38,   24,   40,
       35,   34,   33,   29,   32,   31,   30,   31,   40,   30,
       40,   23,   22,   21,   20,   14,   30,   15,   14,   15,
       24,   24,   24,   28,   14,   40,   28,   28,   36,   36,
       40,   40,   36,   37,   37,   40,   40,   37,    3,   40,

       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
       40,   40,   40,   40,   40,   40,   40,   40
    } ;

static const short int yy_chk[129] =
    {   0,
        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
        1,    1,    1,    1,    1,    1,    1,    1,    1,    7,
       13,   39,    7,    7,    7,    7,    7,   12,   24,   12,
       24,   13,    7,   17,    7,   27,    7,   12,   24,   17,
       25,   25,   28,   38,   13,   37,   27,   36,   26,   25,
       23,   22,   21,   28,   20,   19,   38,   18,   16,   27,
       15,   11,   10,    9,    8,    6,   28,   41,    5,   41,
       42,   42,   42,   43,    4,    3,   43,   43,   44,   44,
        0,    0,   44,   45,   45,    0,    0,   45,   40,   40,

       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
       40,   40,   40,   40,   40,   40,   40,   40,   40,   40,
       40,   40,   40,   40,   40,   40,   40,   40
    } ;

/* the intent behind this definition is that it'll catch
 * any uses of REJECT which flex missed
 */
#define REJECT reject_used_but_not_detected
#define yymore() yymore_used_but_not_detected

/* these variables are all declared out here so that section 3 code can
 * manipulate them
 */
static char *yy_c_buf_p;        /* points to current character in buffer */
static int yy_init = 1;         /* whether we need to initialize */
static int yy_start = 0;        /* start state number */

/* true when we've seen an EOF for the current input file */
static int yy_eof_has_been_seen;

static int yy_n_chars;          /* number of characters read into yy_ch_buf */

/* yy_ch_buf has to be 2 characters longer than YY_BUF_SIZE because we need
 * to put in 2 end-of-buffer characters (this is explained where it is
 * done) at the end of yy_ch_buf
 */
static char yy_ch_buf[YY_BUF_SIZE + 2];

/* yy_hold_char holds the character lost when yytext is formed */
static char yy_hold_char;

static yy_state_type yy_last_accepting_state;
static char *yy_last_accepting_cpos;

#ifdef __STDC__
static yy_state_type yy_get_previous_state( void );
static int yy_get_next_buffer( void );
static void yyunput( int c, char *buf_ptr );
static int input( void );
static void yyrestart( FILE *input_file );
#else
static yy_state_type yy_get_previous_state();
static int yy_get_next_buffer();
static void yyunput();
static int input();
static void yyrestart();
#endif

YY_DECL
    {
    register yy_state_type yy_current_state;
    register char *yy_cp, *yy_bp;
    register int yy_act;




    if ( yy_init )
        {
        if ( ! yy_start )
            yy_start = 1;       /* first start state */

        if ( ! yyin )
            yyin = stdin;

        if ( ! yyout )
            yyout = stdout;

new_file:
        /* this is where we enter upon encountering an end-of-file and
         * yywrap() indicating that we should continue processing
         */

        /* we put in the '\n' and start reading from [1] so that an
         * initial match-at-newline will be true.
         */

        yy_ch_buf[0] = '\n';
        yy_n_chars = 1;

        /* we always need two end-of-buffer characters.  The first causes
         * a transition to the end-of-buffer state.  The second causes
         * a jam in that state.
         */
        yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
        yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;

        yy_eof_has_been_seen = 0;

        yytext = yy_c_buf_p = &yy_ch_buf[1];
        yy_hold_char = *yy_c_buf_p;
        yy_init = 0;
        }

    while ( 1 )         /* loops until end-of-file is reached */
        {
        yy_cp = yy_c_buf_p;

        /* support of yytext */
        *yy_cp = yy_hold_char;

        /* yy_bp points to the position in yy_ch_buf of the start of the
         * current run.
         */
        yy_bp = yy_cp;

        yy_current_state = yy_start;
        do
            {
            register char yy_c = yy_ec[*yy_cp];
            if ( yy_accept[yy_current_state] )
                {
                yy_last_accepting_state = yy_current_state;
                yy_last_accepting_cpos = yy_cp;
                }
            while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = yy_def[yy_current_state];
                if ( yy_current_state >= 41 )
                    yy_c = yy_meta[yy_c];
                }
            yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
            ++yy_cp;
            }
        while ( yy_current_state != 40 );
        yy_cp = yy_last_accepting_cpos;
        yy_current_state = yy_last_accepting_state;

        /* bogus while loop to let YY_BACK_TRACK, EOB_ACT_LAST_MATCH,
         * and EOF actions branch here without introducing an optimizer-
         * daunting goto
         */
        while ( 1 )
            {
            yy_act = yy_accept[yy_current_state];

            YY_DO_BEFORE_ACTION;
            YY_USER_ACTION;

#ifdef FLEX_DEBUG
            fprintf( stderr, "--accepting rule #%d (\"%s\")\n",
                     yy_act, yytext );
#endif

do_action:      /* this label is used only to access EOF actions */
            switch ( yy_act )
                {
                case 0: /* must backtrack */
                /* undo the effects of YY_DO_BEFORE_ACTION */
                *yy_cp = yy_hold_char;
                yy_cp = yy_last_accepting_cpos;
                yy_current_state = yy_last_accepting_state;
                continue; /* go to "YY_DO_BEFORE_ACTION" */

case 1:
# line 55 "l.texread"
{
  /* this was tested on the rather buggy v2.00 of flex which
     gives spurious 'NUL in data' errors.  because of this
     bug, some of the grammar is rather contorted :-(
        in this instance I'd like to be able to recognise
     \documentstyle[]{} explicitly to pull in document-style-
     specific spelling dictionaries. */
  return(WHITESPACE);
}
        YY_BREAK
/* \key and @key.  By accident, @key also subsumes \@key */
case 2:
# line 66 "l.texread"
{
  return(ESCAPE);
}
        YY_BREAK
/* [a-zA-Z]([a-zA-Z\'\-]|\\\-)+ { */
case 3:
# line 72 "l.texread"
{
  /* '+' rather than '*' above means single-letter words are ignored!
     It's pretty good---it handles dashes like these! */
  return(WORD);
}
        YY_BREAK
case 4:
# line 78 "l.texread"
{
  return(WHITESPACE);
}
        YY_BREAK
case 5:
# line 82 "l.texread"
{
  return(WHITESPACE);
}
        YY_BREAK
case 6:
# line 86 "l.texread"
{
  return(WHITESPACE);
}
        YY_BREAK
case 7:
# line 90 "l.texread"
{
  return(WHITESPACE);
}
        YY_BREAK
case 8:
# line 94 "l.texread"
{
  return(WHITESPACE);
}
        YY_BREAK
case 9:
# line 98 "l.texread"
{
  /* The 'not-backslash' before the % isn't ideal, but I'm having trouble
     with this buggy flex trying to do comments properly */
  return(COMMENT);
}
        YY_BREAK
case 10:
# line 104 "l.texread"
{
  return(NEWLINE);
}
        YY_BREAK
case 11:
# line 108 "l.texread"
{
  return(WHITESPACE);
}
        YY_BREAK
case 12:
# line 111 "l.texread"
ECHO;
        YY_BREAK
case YY_STATE_EOF(INITIAL):
    yyterminate();

                case YY_END_OF_BUFFER:
                    /* undo the effects of YY_DO_BEFORE_ACTION */
                    *yy_cp = yy_hold_char;

                    yytext = yy_bp;

                    switch ( yy_get_next_buffer() )
                        {
                        case EOB_ACT_END_OF_FILE:
                            {
                            if ( yywrap() )
                                {
                                /* note: because we've taken care in
                                 * yy_get_next_buffer() to have set up yytext,
                                 * we can now set up yy_c_buf_p so that if some
                                 * total hoser (like flex itself) wants
                                 * to call the scanner after we return the
                                 * YY_NULL, it'll still work - another YY_NULL
                                 * will get returned.
                                 */
                                yy_c_buf_p = yytext;

                                yy_act = YY_STATE_EOF((yy_start - 1) / 2);
                                goto do_action;
                                }

                            else
                                YY_NEW_FILE;
                            }
                            break;

                        case EOB_ACT_RESTART_SCAN:
                            yy_c_buf_p = yytext;
                            yy_hold_char = *yy_c_buf_p;
                            break;

                        case EOB_ACT_LAST_MATCH:
                            yy_c_buf_p = &yy_ch_buf[yy_n_chars];

                            yy_current_state = yy_get_previous_state();

                            yy_cp = yy_c_buf_p;
                            yy_bp = yytext;
                            continue; /* go to "YY_DO_BEFORE_ACTION" */
                        }
                    break;

                default:
                    printf( "action # %d\n", yy_act );
                    YY_FATAL_ERROR( "fatal flex scanner internal error" );
                }

            break; /* exit bogus while loop */
            }
        }
    }


/* yy_get_next_buffer - try to read in new buffer
 *
 * synopsis
 *     int yy_get_next_buffer();
 *
 * returns a code representing an action
 *     EOB_ACT_LAST_MATCH -
 *     EOB_ACT_RESTART_SCAN - restart the scanner
 *     EOB_ACT_END_OF_FILE - end of file
 */

static int yy_get_next_buffer()

    {
    register char *dest = yy_ch_buf;
    register char *source = yytext - 1; /* copy prev. char, too */
    register int number_to_move, i;
    int ret_val;

    if ( yy_c_buf_p != &yy_ch_buf[yy_n_chars + 1] )
        {
        YY_FATAL_ERROR( "NULL in input" );
        /*NOTREACHED*/
        }

    /* try to read more data */

    /* first move last chars to start of buffer */
    number_to_move = yy_c_buf_p - yytext;

    for ( i = 0; i < number_to_move; ++i )
        *(dest++) = *(source++);

    if ( yy_eof_has_been_seen )
        /* don't do the read, it's not guaranteed to return an EOF,
         * just force an EOF
         */
        yy_n_chars = 0;

    else
        {
        int num_to_read = YY_BUF_SIZE - number_to_move - 1;

        if ( num_to_read > YY_READ_BUF_SIZE )
            num_to_read = YY_READ_BUF_SIZE;

        /* read in more data */
        YY_INPUT( (&yy_ch_buf[number_to_move]), yy_n_chars, num_to_read );
        }

    if ( yy_n_chars == 0 )
        {
        if ( number_to_move == 1 )
            ret_val = EOB_ACT_END_OF_FILE;
        else
            ret_val = EOB_ACT_LAST_MATCH;

        yy_eof_has_been_seen = 1;
        }

    else
        ret_val = EOB_ACT_RESTART_SCAN;

    yy_n_chars += number_to_move;
    yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
    yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;

    /* yytext begins at the second character in
     * yy_ch_buf; the first character is the one which
     * preceded it before reading in the latest buffer;
     * it needs to be kept around in case it's a
     * newline, so yy_get_previous_state() will have
     * with '^' rules active
     */

    yytext = &yy_ch_buf[1];

    return ( ret_val );
    }


/* yy_get_previous_state - get the state just before the EOB char was reached
 *
 * synopsis
 *     yy_state_type yy_get_previous_state();
 */

static yy_state_type yy_get_previous_state()

    {
    register yy_state_type yy_current_state;
    register char *yy_cp;

    yy_current_state = yy_start;

    for ( yy_cp = yytext; yy_cp < yy_c_buf_p; ++yy_cp )
        {
        register char yy_c = yy_ec[*yy_cp];
        if ( yy_accept[yy_current_state] )
            {
            yy_last_accepting_state = yy_current_state;
            yy_last_accepting_cpos = yy_cp;
            }
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
            {
            yy_current_state = yy_def[yy_current_state];
            if ( yy_current_state >= 41 )
                yy_c = yy_meta[yy_c];
            }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
        }

    return ( yy_current_state );
    }


#ifdef __STDC__
static void yyunput( int c, register char *yy_bp )
#else
static void yyunput( c, yy_bp )
int c;
register char *yy_bp;
#endif

    {
    register char *yy_cp = yy_c_buf_p;

    *yy_cp = yy_hold_char; /* undo effects of setting up yytext */

    if ( yy_cp < yy_ch_buf + 2 )
        { /* need to shift things up to make room */
        register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */
        register char *dest = &yy_ch_buf[YY_BUF_SIZE + 2];
        register char *source = &yy_ch_buf[number_to_move];

        while ( source > yy_ch_buf )
            *--dest = *--source;

        yy_cp += dest - source;
        yy_bp += dest - source;

        if ( yy_cp < yy_ch_buf + 2 )
            YY_FATAL_ERROR( "flex scanner push-back overflow" );
        }

    if ( yy_cp > yy_bp && yy_cp[-1] == '\n' )
        yy_cp[-2] = '\n';

    *--yy_cp = c;

    YY_DO_BEFORE_ACTION; /* set up yytext again */
    }


static int input()

    {
    int c;
    char *yy_cp = yy_c_buf_p;

    *yy_cp = yy_hold_char;

    if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
        { /* need more input */
        yytext = yy_c_buf_p;
        ++yy_c_buf_p;

        switch ( yy_get_next_buffer() )
            {
            /* this code, unfortunately, is somewhat redundant with
             * that above
             */
            case EOB_ACT_END_OF_FILE:
                {
                if ( yywrap() )
                    {
                    yy_c_buf_p = yytext;
                    return ( EOF );
                    }

                yy_ch_buf[0] = '\n';
                yy_n_chars = 1;
                yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
                yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
                yy_eof_has_been_seen = 0;
                yytext = yy_c_buf_p = &yy_ch_buf[1];
                yy_hold_char = *yy_c_buf_p;

                return ( input() );
                }
                break;

            case EOB_ACT_RESTART_SCAN:
                yy_c_buf_p = yytext;
                break;

            case EOB_ACT_LAST_MATCH:
                YY_FATAL_ERROR( "unexpected last match in input()" );
            }
        }

    c = *yy_c_buf_p;
    yy_hold_char = *++yy_c_buf_p;

    return ( c );
    }


#ifdef __STDC__
static void yyrestart( FILE *input_file )
#else
static void yyrestart( input_file )
FILE *input_file;
#endif

    {
    if ( yyin != stdin )
        fclose( yyin );

    yyin = input_file;
    yy_init = 1;
    }
# line 111 "l.texread"
