/******************************/
/*Author R.G.Jones Jan 2001   */
/*                            */
/*Feel free to hack/use this  */
/*with no conditions attached */
/******************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>

#define FALSE 0
#define TRUE 1
#define EXTRA_SPACE 0x8000	/*the amount of space to add each time the array needs resizing*/

/********************/
/*Global variables*/
/********************/
long  stopMe;	/*to allow for a graceful exit*/
size_t  count;		/*number of primes found so far*/
size_t space;		/*number of storage spaces available for primes*/
long *primesFound;	/*pointer to array of primes*/
long *primesPos;	/*pointer within primes array*/

/***************************/
/*Signal handler to close the program gracefully on Cntrl-c*/
/***************************/
void closeMe(int signum)
{
/*set the variable to allow the program to know it is to stop*/
stopMe=TRUE;
printf("\nControl-C Pressed\n");
}

/*******************************************/
/*Xmalloc to set up data arrays*/
/*******************************************/
void * xmalloc(size_t size)
{
void * temp;
temp=malloc(size*sizeof(long));/*put it onto a page boundary*/
if (temp==NULL)
	{
	printf("Xmalloc failed to create memory\n");
	return NULL;
	}
else
	{
	return temp;
	}
}

/***********************************************/
/*xTend to resize the arrays automatically*/
/***********************************************/
void xTend(void * ptr)
{
register void * temp;
space += EXTRA_SPACE;
/*printf("Space= %i\n",space);*/
temp=realloc(ptr,space*sizeof(long));
if (temp==NULL)
	{
	/*operation failed-exit gracefully*/
	printf("Failed to correctly resize array\n");
	stopMe=TRUE;
	}
else
	{
	primesFound=(long *)temp;
	primesPos=(long *)temp+count;
	}
}

/**************************************/
/*is the number a prime or not?*/
/**************************************/
int isPrime(long myNum)
{
long max,*testNum;
size_t i;
ldiv_t result;
int prime;

prime=TRUE;/*assume is a prime until proved otherwise*/
i=0;
testNum=primesFound;
do
    {
    result=ldiv(myNum,*testNum++);
    if(result.rem==0)
        {
        /*the number is properly divisible*/
        prime=FALSE;
        }
    /*each time the division fails to be whole, you can*/
    /*ignore a whole new set of numbers*/
    max=result.quot;
    }while ((prime) && (*testNum<max) && (++i<count));
return prime;
}

/****************************************/
/*main program*/
/****************************************/
int main (int argc, char **argv)
{
long testMe,elin,pcount,ncount;
size_t i;
clock_t start,end;
double thisTime;
FILE *out;

/*set the program to keep running*/
stopMe=FALSE;
/*set up the handler to catch the Control-c signal*/
signal(SIGINT,closeMe);/*cntrl-c*/
signal(SIGTERM,closeMe);/*kill (unix)*/

/*create the array for storing primes*/
space=EXTRA_SPACE;
primesFound=(long *)xmalloc(space);
primesPos=primesFound;/*point to beginning of array*/

/*set the values to first run values*/
testMe=11;
*primesPos++=3;
count++;
*primesPos++=5;
count++;
*primesPos++=7;
count++;
ncount=3;
printf("Working...\n");
printf("Press Control-c to exit\n");
/*prime numbers must end in 1,3,7 or 9*/
start=clock();
while ((!stopMe) && (testMe<10000000))
    {
    if (isPrime(testMe))
        {
        if(ncount++>100000)
            {
            putchar('.');
            ncount=0;
            }
        *primesPos++=testMe;
        count++;
        if (count==(space-1)) xTend(primesFound);
        }
    testMe+=2;
    }
    
/*check the timing*/
end=clock();
thisTime=((double)(end-start))/CLOCKS_PER_SEC;
printf("Time spend processing in this session=%g\n",thisTime);
printf("\nFound %i new prime numbers\n",count-3);

printf("\nPrinting numbers to file : results\n");
/*now print the results to the file*/
/*open the output file*/
out=fopen("results","w");
if (out==NULL)
	{
	printf("Cannot open file to write results\nQuitting.\n");
	exit(1);
	}
pcount=0;
for (i=0,primesPos=primesFound;i<count;i++)
    {
    fprintf(out,"%8x ",*primesPos++);
    if (++pcount>6)
         {
         pcount=0;
         fprintf(out,"\n");
         } 
    }
fclose(out);

free(primesFound);
return 0;
}
