/* ------------------------------------------------------------------ */
  /*  One-shot program to administer Jeff Earls' SQUID PURITY TEST(tm)  */
  /*  No rights reserved.   H. Marc Lewis, 12-Feb-1993                  */
  /* ------------------------------------------------------------------ */
  
  /*
   * support for local squid test and divisor
   * Kay Marquardt, 7-June-1996, kay@rrr.net
   *
   * store and continue squid test
   * Kay Marquardt, 28-July-1996, kay@rrr.net
   *
   * support local "numeric answer"
   * Kay Marquardt, 14-Aug-1996, kay@rrr.net
   */
  
  /*
   * the squid test need the following files:
   *
   * 	purity.doc	text shown in front of the test
   *	purity.txt	the squid test questions
   *
   *	purity.div	optional configuration file to support new
   *			or local versions of squid test:
   *
  
  <divisor> <#questions>
  <numeric answer required text>
  
   *			default values:
  
  39.16	990
  numeric answer required
  
   *			german example:
  
  34.16 1010
  numerische Antwort erforderlich
  
   */
  
  /*
   * simple local squid test support:
   *
   * if the dir LANG exist, squid.c show the avail dirs
   * and change to the given one
   *
   * examples:
   *		LANG/english/<SQUIDFILES>
   *		LANG/deutsch/<SQUIDFILES>
   */
  
  
  /*
   * the results are stored and retrieved from the dir RESULT in the
   * used directory.
   *
   * examples:
   *		RESULT/my_squid
   *		LANG/english/RESULT/dave
   *		LANG/deutsch/RESULT/someone
   *
   */
  
  
  
  /*
   * define SHOWDIR and MORE to the commands on your system
   */
  
  /*#define SHOWDIR	"dir" /* DOS style  */
  #define SHOWDIR		"ls"  /* UNIX Style */
  
  #define MORE		"more" /* DOS and UNIX, max. 52 characters */
  
  #include <stdio.h>
  #include <string.h>
  
  #define FALSE (0)
  #define ABNORMALFORM	-9999
  #define TRUE  (!FALSE)
  
  float sqDiv=33.96;	/* squid divisor   */
  int   numQuest=990;	/* # of questions  */
  int   aktQuest=0;	/* actual question */
  int   score = 0;	/* actual score    */
  
  char  *lang;
  
  char  *numReq[256]="numeric answer required,";
  
  int   table[]= {-1,2,4,7,10};	/* numeric answer  */
  
  main()
  {
  	char	line[256];
  	FILE	*fp;
  	int	ans;
  	int	yes;
  	int	ch=0;
  
  	lang="unknown";
  
  	/* multi language support */
  	if(chdir("LANG") == 0) selectLanguage();
  
  	help();
  
  	/* restart with last values */
  	if(chdir("RESULT") == 0) getResult();
  
  	getSquidDiv();
  
  	fp = fopen("purity.txt","r");
  	if (fp == 0) {
  		puts("ERROR: can't open file `purity.txt'");
  		exit(1);
  		}
  
  	/* skip always answered questions */
  	while (ch < aktQuest) {
  		nextquestion(fp, &yes, TRUE);
  		ch++;
  	}
  
  
  	/* let's go */
  	while (nextquestion(fp, &yes, FALSE)) {
  		if (yes == ABNORMALFORM)
  			printf("*** %s,  -1=A, 2=B, 4=C, 7=D, 10=E ***\n", numReq);
  
  		aktQuest++;
  		for (;;) {
  			printf("%d <%4.2f> (Quit, Save, ?): ", aktQuest,(float)score/sqDiv);
  			fflush(stdout);
  			gets(line);
  			if (line[0] == 's' || line[0] == 'S') {
  				/* save result, actual question not answered*/
  				aktQuest--;
  				save(score,"?");
  				aktQuest++;
  				continue;
  				}
  			if (line[0] == 'q' || line[0] == 'Q') {
  				/* quit, actual auestion not answered */
  				aktQuest--;
  				finish(score);
  				return;
  				}
  			if (line[0] == '?') {
  				help();
  				continue;			/* to avoid the goto */
  				}
  			break;
  			}
  
  		if (yes == ABNORMALFORM) {
  			ch = line[0] & 0xDF;	/* fold lower case */
  			if (ch >= 'A' && ch <= 'E') {
  				yes = table[ch-'A'];
  				line[0] = 'y';
  				}
  			}
  
  		if (line[0] == 'y' || line[0] == 'Y')
  			ans = yes;
  		else
  			ans = atoi(line);
  		score += ans;
  		printf("ans=%d\n",ans);
  		}
  	finish(score);
  	save(score,"?");
  }
  
  nextquestion(fp,yes, skip)
  	FILE *fp;
  	int *yes;
  	int skip;
  {
  	char	line[256];
  	char	*cp;
  	short	skipblanklines = TRUE;
  	static int eof = FALSE;
  
  	if (eof)
  		return(0);
  	/* Skip over blank lines */
  	*yes = ABNORMALFORM;							/* assume error */
  	if(!skip) putchar('\n');
  	while (fgets(line,sizeof(line),fp)) {
  		for(cp=line; *cp==' ' || *cp=='\t'; cp++) ;	/* skip blanks and tabs */
  
  		if (*cp == '\n' || *cp == '\0') {
  			if (skipblanklines)
  				continue;
  			else
  				return(1);
  			}
  		skipblanklines = FALSE;
  
  		if (strncmp(line,"---",3) == 0) {		/* skip comments */
  			fgets(line,sizeof(line),fp);
  			fgets(line,sizeof(line),fp);
  			fgets(line,sizeof(line),fp);
  			}
  
  		if (!skip) printf(line);
  		if ((cp = strrchr(line,'(')) && cp[1] == '-')
  			*yes = -atoi(&cp[2]);
  		else if ((cp = strrchr(line,'(')) && cp[1] == '+')
  			*yes = atoi(&cp[2]);
  		}
  	eof = TRUE;
  	return(1);
  }
  
  
  finish(score)
  	int score;
  {
  	save(score,"");
  }
  
  save(score,file)
  	int score;
  	char *file;
  {
  	FILE *out=0;
  	char input[256];
  
  	if (file == 0 || *file =='\0') {
  		out=stdout;
  	} else {
  		mkdir("RESULT",0777);
  		if(chdir("RESULT") != 0) {
  			printf("\nError: can't change to RESULT dir\n");
  			return;
  		}
  
  		strcpy(input, file);
  
  		if(*file == '?'){
  			printf("\nAlways saved results:\n");
  			system(SHOWDIR);
  			printf("\nEnter filename to save result, nothing to abort: ");
  			gets(input);
  
  			/* no input, abort */
  			if(*input=='\0') {
  				printf("No filename given, abort ...\n\n");
  				chdir("..");
  				return;
  			}
  		}
  
  		if((out=fopen(input,"w")) == 0) {
  			printf("\nERROR: can't write result to 'RESULT/%s'\n", input);
  			chdir("..");
  			return;
  		}
  		chdir("..");
  	}
  	fprintf(out,"\nYour degree-of-squidliness is:\n");
  	fprintf(out,"%4.2f after %d of %d questions.\n",
  		(float)score/sqDiv, aktQuest, numQuest);
  	fprintf(out,"Test language was: `%s'\n", lang);
  	fflush(out);
  
  	if(out != 0) close(out);
  }
  
  getResult()
  {
  	FILE *df;
  	float oldRes;
  	int num;
  	char input[256];
  
  	printf("\nSelect one of saved results:\n\n");
  
  	system(SHOWDIR);
  
  	printf("\nPlease enter filename, nothing to abort: ");
  	fflush(stdout);
  
  	gets(input);
  
  	/* no input, abort */
  	if(*input=='\0') {
  		printf("No file selected, we start squid from the beginning ...\n\n");
  		fflush(stdout);
  		chdir("..");
  		return;
  	}
  
  
  	/* try to open file */
  	if((df=fopen(input, "r")) == 0) {
  		printf("ERROR: can't open file, retry.\n\n");
  		getResult();
  		return;
  	}
  
  	*input = '\0';
  	fgets(input,sizeof(input),df);
  	fgets(input,sizeof(input),df);
  	fgets(input,sizeof(input),df);
  	fclose(df);
  
  	if(sscanf(input, "%f after %d", &oldRes, &num) == 2) {
  		aktQuest=num;
  		score=oldRes*sqDiv;
  	} else {
  		printf("File has wrong format, we start squid from the beginning ...\n\n");
  	}
  
  	fflush(stdout);
  	chdir("..");
  	return;
  }
  
  
  help()
  {
  	char	line[64];
  
  	strcpy(line, MORE);
  	strcat(line, " purity.doc");
  	system(line);
  }
  
  
  selectLanguage()
  {
  static	char input[256];
  
  	printf("\nSelect one of the following languages:\n\n");
  
  	system(SHOWDIR);
  
  	printf("\nPlease enter language, nothing to abort: ");
  	fflush(stdout);
  
  	gets(input);
  
  	/* no input, abort */
  	if(*input=='\0') {
  		printf("No language selected, use start directory ...\n\n");
  		fflush(stdout);
  		chdir("..");
  		return;
  	}
  
  	/* we can't change to dir, retry */
  	if(chdir(input)!=0) {
  		printf("ERROR: unkown language, retry.\n\n\n");
  		selectLanguage();
  		return;
  	}
  
  	lang=input;
  
  	printf("\nSelected language: `%s'\n\n", lang);
  	fflush(stdout);
  	return;
  }
  
  
  getSquidDiv()
  {
  	FILE *df;
  	float  div;
  	int num;
  	char tmpStr[256];
  
  	if((df=fopen("purity.div", "r")) != 0) {
  	    if(fgets(tmpStr, sizeof(tmpStr)-1, df) != 0) {
  		/* first line: divisor and # of questions */
  		switch(sscanf(tmpStr, "%f %d", &div, &num)) {
  			case 2:	numQuest = num;
  			case 1: sqDiv = div;
  		}
  
  		/* second line: numeric answer text */
  		if(fgets(tmpStr, sizeof(tmpStr)-1, df) != 0) {
  
  		    /* line not empty, remove \n and store */
  		    if(*tmpStr != '\0' && *tmpStr != '\n') {
  			num=strlen(tmpStr);
  			if(tmpStr[num-1]='\n') tmpStr[num-1]='\0';
  
  			strcpy(numReq, tmpStr);
  		    }
  		}
  	    }
  	}
  	printf("\nThe squid divisor is `%2.2f', there are `%d' questions.\n\n"
  			, sqDiv, numQuest);
  	fflush(stdout);
  }
