/*
 * This file is part of flex.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 
 * Neither the name of the University nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

%{
/* A scanner file to build "scanner.c".
   Input language is any text made of spaces, newlines, and alphanumerics.

   We create N_THREADS number of threads. Each thread has it's own scanner.
   Each thread selects one of the files specified in ARGV, scans it, then
   closes it. This is repeated N_SCANS number of times for each thread.

   The idea is to press the scanner to break under threads.
   If we see  "Scanner Jammed", then we know

*/
#include <stdio.h>
#include <stdlib.h>
#include <config.h>

#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif

/* A naive test for segfaults when accessing yytext. */
static int process_text(char* s, yyscan_t  scanner);

%}

%option 8bit prefix="test"
%option nounput nomain nodefault noinput
%option yywrap
%option reentrant
%option warn

    /* Arbitrary states.*/
%x STATE_1
%x STATE_2

%%

    #define NUMBER 200
    #define WORD   201

<INITIAL>[[:digit:]]+ { yybegin(STATE_1); process_text(yytext,yyscanner); return NUMBER; }
<INITIAL>[[:alpha:]]+ { yybegin(STATE_2); process_text(yytext,yyscanner); return WORD; }

<STATE_1>[[:alpha:]]+ { yybegin(0); process_text(yytext,yyscanner); return WORD; }
<STATE_1>[[:digit:]]+ { yybegin(0); process_text(yytext,yyscanner); return NUMBER; }

<STATE_2>[[:alpha:]]+ { yybegin(0); process_text(yytext,yyscanner); return WORD; }
<STATE_2>[[:digit:]]+ { yybegin(0); process_text(yytext,yyscanner); return NUMBER; }

<INITIAL,STATE_1,STATE_2>" "|\t|\r|\n { process_text(yytext,yyscanner); }
<INITIAL,STATE_1,STATE_2>[^[:alnum:][:space:]\t\r\n] {
        /*fprintf(stderr,"*** Error: bad input char '%c'.\n", yytext[0]); */
        yyterminate();
    }
<INITIAL,STATE_1,STATE_2>[[:space:]\r\n]+  { }
%%

int testwrap( yyscan_t  scanner) {
    (void)scanner;
    return 1;
}
static int process_text(char* s, yyscan_t  scanner)
{
    (void)scanner;
    return (int)(*s) + (int) *(s + testget_leng(scanner)-1);
}

int main(int ARGC, char *ARGV[]);

#ifndef HAVE_PTHREAD_H
int main (int ARGC, char *ARGV[]) {
    puts(
       "TEST ABORTED because pthread library not available \n"
       "-- This is expected on some systems. It is not a flex error.");
    /* Exit status for a skipped test */
    return 77;
}
#else

#define N_THREADS 4
#define N_SCANS   20

/* Each thread selects the next file to scan in round-robin fashion.
   If there are less files than threads, some threads may block. */

static pthread_mutex_t next_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t go_ahead  = PTHREAD_MUTEX_INITIALIZER;
static int n_files, next_file;

static pthread_mutex_t *file_locks;
static char **filenames;


static void * thread_func ( void* arg )
{
    int i;

    (void)arg;

    /* Wait for go-ahead. */
    pthread_mutex_lock( &go_ahead);
    pthread_mutex_unlock(&go_ahead);

    for( i =0 ; i < N_SCANS ; i++ )
    {
        int next;
        yyscan_t  scanner;
        FILE * fp;

        pthread_mutex_lock ( &next_lock );
        next = (next_file++) % n_files;
        pthread_mutex_unlock ( &next_lock );

        pthread_mutex_lock ( &file_locks[ next ] );

        testlex_init( &scanner );
        /*printf("Scanning file %s  #%d\n",filenames[next],i); fflush(stdout); */
        if((fp = fopen(filenames[next],"r"))==NULL) {
            perror("fopen");
            return NULL;
        }
        testset_in(fp,scanner);

        while( testlex( scanner) != 0)
        {
        }
        fclose(fp);
        testlex_destroy(scanner);
        pthread_mutex_unlock ( &file_locks[ next ] );
    }
    return NULL;
}

int main (int ARGC, char *ARGV[])
{
    int i;
    pthread_t threads[N_THREADS];

    if( ARGC < 2 ) {
        fprintf(stderr,"*** Error: No filenames specified.\n");
        exit(-1);
    }

    /* Allocate and initialize the locks. One for each filename in ARGV. */
    file_locks = malloc((size_t) (ARGC-1) * sizeof(pthread_mutex_t));
    for( i = 0; i < ARGC-1; i++)
        pthread_mutex_init( &file_locks[i], NULL );

    n_files = ARGC -1;
    filenames = ARGV + 1;
    next_file = 0;

    /* prevent threads from starting until all threads have been created. */
    pthread_mutex_lock(&go_ahead);

    /* Create N threads then wait for them. */
    for(i =0; i < N_THREADS ; i++ ) {
        if( pthread_create( &threads[i], NULL, thread_func, NULL) != 0)
        {
            fprintf(stderr, "*** Error: pthread_create failed.\n");
            exit(-1);
        }
        printf("Created thread %d.\n",i); fflush(stdout);
    }

    /* Tell threads to begin. */
    pthread_mutex_unlock(&go_ahead);

    for(i =0; i < N_THREADS ; i++ ) {
        pthread_join ( threads[i], NULL );
        printf("Thread %d done.\n", i ); fflush(stdout);
    }

    for( i = 0; i < ARGC-1; i++)
        pthread_mutex_destroy( &file_locks[i] );

    pthread_mutex_destroy( &next_lock );
    pthread_mutex_destroy( &go_ahead );
    free( file_locks );
    printf("TEST RETURNING OK.\n");
    return 0;
}

#endif /* HAVE_PTHREAD_H */

