Exemple #1
0
TIN::TIN() : mMesh(NULL), mBehavior(NULL), mRecentTri(NULL), mMinZ(std::numeric_limits<double>::max()), mMaxZ(-1 * std::numeric_limits<double>::max())
{
	mMesh = new TMesh;
	mBehavior = new TBehavior;
	mRecentTri = new TOrientedTriangle;

	// Using incremental algorithm for triangulation
	char * switches = {"zQ"}; 

	triangleinit(mMesh);

	parsecommandline(1, &switches, mBehavior);

	mRecentTri->tri = NULL;
	mRecentTri->orient = 0;
}
Exemple #2
0
/* This function should be called from main() to configure the program.
 * After the configurations have been initialized the command line is
 * parsed.  Then the configuration file is read and after that if any
 * parameter has not been set the defaults are used. */
int
opt_configure(int argc, const char *argv[])
{    
    initconfig();
    parsecommandline(argc, argv);
    if(readconfigfile()) {
        xerror("Unable to read configuration running with defaults");
    }
    setdefaults();
    
//    xlog(LOG_CONFIG, "Daemonize set to %d", _daemonize);
//    xlog(LOG_CONFIG, "Status Tagname is set to %s", _statustag);
//    xlog(LOG_CONFIG, "PID File Name set to %s", _pidfile);
    
    return 0;
}
Exemple #3
0
int cmd_call(char *param)
{
/*
 * Perform CALL command.
 *
 * Allocate a new batch context and add it to the current chain.
 * Call parsecommandline passing in our param string
 * If No batch file was opened then remove our newly allocted
 * context block.
 */

	struct bcontext *n = newBatchContext();
	int ec;

	if (n == 0) {
		/* Not in a batch file */
		return 1;
	}

	optS = optN = 0;

	if((ec = leadOptions(&param, opt_call, 0)) != E_None)
		return ec;

	if(swapOnExec != ERROR) {
		if(optS)
			swapOnExec = TRUE;
		if(optN)
			swapOnExec = FALSE;
	}

	parsecommandline(param, FALSE);
	if(swapOnExec != ERROR)
		swapOnExec = FALSE;

	if (bc->bfile == 0
	 && bc->bfnam == 0) {    /* Wasn't a batch file so remove context */
		bc = bc->prev;
		free(n);
	}

	return 0;
}
Exemple #4
0
/*
 * do the prompt/input/process loop
 *
 *  If xflg is true, the function will not go interactive, but returns.
 *  If commandline != NULL, this command is processed first.
 *
 *  Return: 0: on success
 */
int process_input(int xflag, char *commandline)
{
    /* Dimensionate parsedline that no sprintf() can overflow the buffer
     */
  char parsedline[MAX_INTERNAL_COMMAND_SIZE + sizeof(errorlevel) * 8]
    , *readline;
/* Return the maximum pointer into parsedline to add 'numbytes' bytes */
#define parsedMax(numbytes)   \
  (parsedline + MAX_INTERNAL_COMMAND_SIZE - 1 - (numbytes))
  char *evar;
  char *tp;
  char *ip;
  char *cp;
  char forvar;
  int echothisline;
  int tracethisline;

  do
  {
  	interactive_command = 0;		/* not directly entered by user */
  	echothisline = tracethisline = 0;
    if(commandline) {
      ip = commandline;
      readline = commandline = NULL;
    } else {
    if ((readline = malloc(MAX_INTERNAL_COMMAND_SIZE + 1)) == NULL)
    {
      error_out_of_memory();
      return 1;
    }

      if (NULL == (ip = readbatchline(&echothisline, readline,
                      MAX_INTERNAL_COMMAND_SIZE)))
      { /* if no batch input then... */
      if (xflag   /* must not go interactive */
       || (fdattr(0) & 0x84) == 0x84  /* input is NUL device */
       || feof(stdin))    /* no further input */
      {
        free(readline);
        break;
      }

      /* Go Interactive */
		interactive_command = 1;		/* directly entered by user */
      readcommand(ip = readline, MAX_INTERNAL_COMMAND_SIZE);
      tracemode = 0;          /* reset trace mode */
      }
    }

    /* 
     * The question mark '?' has a double meaning:
     *	C:\> ?
     *		==> Display short help
     *
     *	C:\> ? command arguments
     *		==> enable tracemode for just this line
     */
    if(*(ip = trim(ip)) == '?') {
    	 ip = trim(ip + 1);
    	 if(!*ip) {		/* is short help command */
#ifdef INCLUDE_CMD_QUESTION
    	 	showcmds(ip);
#endif
			free(readline);
			continue;
		}
		/* this-line-tracemode */
		echothisline = 0;
		tracethisline = 1;
	}

  /* The FOR hack
    If the line matches /^\s*for\s+\%[a-z]\s/, the FOR hack
    becomes active, because FOR requires the sequence "%<ch>"
    in its input.
    When the percent (%) expansion is made later on, any
    sequence "%<ch>" is retained.
  */
  cp = ip;
  if(matchtok(cp, "for") && *cp == '%' && isalpha(cp[1])
   && isspace(cp[2]))   /* activate FOR hack */
    forvar = toupper(cp[1]);
  else forvar = 0;

  cp = parsedline;
    while (*ip)
    {
      /* Assume that at least one character is added, place the
        test here to simplify the switch() statement */
      if(cp >= parsedMax(1)) {
        cp = NULL;    /* error condition */
        break;
      }
      if (*ip == '%')
      {
        switch (*++ip)
        {
          case '\0':    /* FOR hack forvar == 0 if no FOR is active */
            *cp++ = '%';
            break;

          case '%':
            *cp++ = *ip++;
            break;

          case '0':
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '8':
          case '9':
            if (NULL != (tp = find_arg(*ip - '0')))
            {
              if(cp >= parsedMax(strlen(tp))) {
                cp = NULL;
                goto intBufOver;
              }
              cp = stpcpy(cp, tp);
              ip++;
            }
            else
              *cp++ = '%';
              /* Let the digit be copied in the cycle */

            break;

          case '?':
            /* overflow check: parsedline has that many character
              "on reserve" */
            cp += sprintf(cp, "%u", errorlevel);
            ip++;
            break;

          default:
            if(forvar == toupper(*ip)) {    /* FOR hack */
              *cp++ = '%';			/* let the var be copied in next cycle */
              break;
            }
            if ((tp = strchr(ip, '%')) != NULL)
            {
              *tp = '\0';

              if ((evar = getEnv(ip)) != NULL) {
                if(cp >= parsedMax(strlen(evar))) {
                  cp = NULL;
                  goto intBufOver;
                }
                cp = stpcpy(cp, evar);
               }

              ip = tp + 1;
            }
            break;
        }
        continue;
      }

      if (iscntrl(*ip))
        *cp = ' ';
      else 
      	*cp++ = *ip++;
    }

intBufOver:
    free(readline);

  if(!cp) {     /* internal buffer overflow */
    error_line_too_long();
    continue;
  }

    *cp = '\0';   /* terminate copied string */

    if (echothisline)           /* Echo batch file line */
    {
      printprompt();
      puts(parsedline);
    }

    if (*parsedline)
    {
      if(tracethisline)
      	++tracemode;
      parsecommandline(parsedline);
      if(tracethisline)
      	--tracemode;
      if (echothisline || echo)
        putchar('\n');
    }
  }
  while (!canexit || !exitflag);

  return 0;
}
Exemple #5
0
int cmd_if(char *param)
{

#define X_EXEC 1

	char *pp;

	int x_flag = 0;       /* when set cause 'then' clause to be exec'ed */
	int negate = 0;       /* NOT keyword present */
	int ignore_case = 0;  /* /I option, case insensitive compare */


	/* First check if param exists */
	assert(param);

	/* check for options, note non-options must be treated as part of comparision */
      if (matchtok(param, "/I")||matchtok(param, "/i"))
        ignore_case++;

	/* next check if param string begins with word 'not' */
	if(matchtok(param, "not"))
		negate = X_EXEC;            /* Remember 'NOT' */

	/* Check for 'exist' form */

	if(matchtok(param, "exist")) {
		struct dos_ffblk f;
		isr olderrhandler;

		if(!*param) {
			/* syntax error */
			error_if_exist();
			return 0;
		}

		pp = skip_word(param);
		*pp++ = '\0';

		/* don't show abort/retry/fail if no disk in drive */
		get_isr(0x24, olderrhandler);
#ifdef XMS_SWAP
		set_isrfct(0x24, autofail_err_handler);  /* always fails */
#else
		set_isrfct(0x24, dummy_criter_handler);  /* always fails */
#endif

		if(dos_findfirst(param, &f, FA_NORMAL|FA_ARCH|FA_SYSTEM|FA_RDONLY|FA_HIDDEN) == 0)
			x_flag = X_EXEC;
		dos_findclose(&f);
        
		/* restore critical error handler */
		set_isrfct(0x24, olderrhandler);
	}

	/* Check for 'errorlevel' form */

	else if(matchtok(param, "errorlevel")) {
		int n = 0;

#if 0
		if(!isdigit(*param)) {
			error_if_errorlevel();
			return 0;
		}

		pp = param;
		do  n = n * 10 + (*pp - '0');
		while (isdigit(*++pp));

		if(*pp && !isargdelim(*pp)) {
			error_if_errorlevel_number();
			return 0;
		}
#else
		/* Add this COMMAND bug as someone tries to use:
			IF ERRORLEVEL H<upper-case_letter>
			-or-
			IF ERRORLEVEL x<lower-case_letter>

			to match the errorlevel against drive letters.
			NOT supported by 4dos or WinNT.

			HA --> maps to errorlevel 1
			xa --> same

			HB & xb --> to 2
			a.s.o.
		*/

		if(!*param) {
			error_if_errorlevel();
			return 0;
		}
		pp = param;
		do  n = n * 10 + (*pp - '0');
		while(*++pp && !isargdelim(*pp));
		n &= 255;
		dprintf( ("IF: checking for ERRORLEVEL >= %u\n", n) );
#endif

		if(errorlevel >= n)
			x_flag = X_EXEC;
	}

	/* Check that '==' is present, syntax error if not */
	else {
		size_t len;
		char *r;      /* right operand */

		pp = skipqword(param, "==");

		if(*pp != '=' || pp[1] != '=') {
			error_syntax(0);
			return 0;
		}

		*pp = '\0';     /* param[] points to the left operand */

		/* skip over the '==' and subsquent spaces and
			assign the end of the right operator to pp */
		pp = skipqword(r = ltrimcl(pp + 2), 0);

		/*	now: param := beginning of the left operand
			r := beginning of the right operand
			pp := end of right operand
		*/

		rtrimcl(param);      /* ensure that spurious whitespaces are ignored */
		len = strlen(param);

		/* check if strings differ */
		if ( ((pp - r) == len) &&
		     ((ignore_case && strnicmp(param, r, len) == 0) ||
		      (memcmp(param, r, len) == 0)) )
			x_flag = X_EXEC;
	}

	if(x_flag ^ negate)		/* perform the command */
		if(!*(pp = ltrimcl(pp)))
			error_if_command();
		else
			parsecommandline(pp, FALSE);

	return 0;
}
    // Customized triangulation call.
    void custom_triangulate(char *triswitches, struct triangulateio *in, struct triangulateio *out, struct triangulateio *vorout, const int *outside, const int *inside)
    {
        struct mesh m;
        struct behavior b;
        //REAL *holearray;
        //REAL *regionarray;
        triangleinit(& m);
        parsecommandline(1, & triswitches, & b);
        //b.verbose=2;
        m.steinerleft = b.steiner;
        transfernodes(& m, & b, in->pointlist, in->pointattributelist,
                      in->pointmarkerlist, in->numberofpoints,
                      in->numberofpointattributes);
        if ( b.refine ) {
            m.hullsize = reconstruct(& m, & b, in->trianglelist,
                                     in->triangleattributelist, in->trianglearealist,
                                     in->numberoftriangles, in->numberofcorners,
                                     in->numberoftriangleattributes,
                                     in->segmentlist, in->segmentmarkerlist,
                                     in->numberofsegments);
        } else {
            m.hullsize = delaunay(& m, & b);
        }
        m.infvertex1 = ( vertex ) NULL;
        m.infvertex2 = ( vertex ) NULL;
        m.infvertex3 = ( vertex ) NULL;
        if ( b.usesegments ) {
            m.checksegments = 1;
            if ( !b.refine ) {
                formskeleton(& m, & b, in->segmentlist,
                             in->segmentmarkerlist, in->numberofsegments);
            }
        }
 #if 0
        struct osub subsegloop;
        traversalinit(& m.subsegs);
        subsegloop.ss = subsegtraverse(& m);
        subsegloop.ssorient = 0;
        while ( subsegloop.ss != ( subseg * ) NULL ) {
            if ( subsegloop.ss != m.dummysub ) {
                REAL *p1, *p2;
                sorg(subsegloop, p1);
                sdest(subsegloop, p2);
                printf("  Connected (%f,%f) to (%f,%f)\n", p1 [ 0 ], p1 [ 1 ], p2 [ 0 ], p2 [ 1 ]);
                subsegloop.ss = subsegtraverse(& m);
            }
        }
 #endif
        if ( b.poly && ( m.triangles.items > 0 ) ) {
            //holearray = in->holelist;
            m.holes = in->numberofholes;
            //regionarray = in->regionlist;
            m.regions = in->numberofregions;
            if ( !b.refine ) {
                /* Only increase quality if the regions are properly defined. */
                int sane = custom_carveholes(& m, & b, outside, inside);
                b.quality *= sane;
                if ( sane == 0 ) {
                    printf("Probably bad PSLG\n");
                    exit(-1);
                }
            }
        } else {
            m.holes = 0;
            m.regions = 0;
        }
        if ( b.quality && ( m.triangles.items > 0 ) ) {
            enforcequality(& m, & b);
        }
        m.edges = ( 3l * m.triangles.items + m.hullsize ) / 2l;
        if ( b.order > 1 ) {
            highorder(& m, & b);
        }
        if ( !b.quiet ) {
            printf("\n");
        }
        if ( b.jettison ) {
            out->numberofpoints = m.vertices.items - m.undeads;
        } else {
            out->numberofpoints = m.vertices.items;
        }
        out->numberofpointattributes = m.nextras;
        out->numberoftriangles = m.triangles.items;
        out->numberofcorners = ( b.order + 1 ) * ( b.order + 2 ) / 2;
        out->numberoftriangleattributes = m.eextras;
        out->numberofedges = m.edges;
        if ( b.usesegments ) {
            out->numberofsegments = m.subsegs.items;
        } else {
            out->numberofsegments = m.hullsize;
        }
        if ( vorout != ( struct triangulateio * ) NULL ) {
            vorout->numberofpoints = m.triangles.items;
            vorout->numberofpointattributes = m.nextras;
            vorout->numberofedges = m.edges;
        }
        if ( b.nonodewritten || ( b.noiterationnum && m.readnodefile ) ) {
            if ( !b.quiet ) {
                printf("NOT writing vertices.\n");
            }
            numbernodes(& m, & b);
        } else {
            writenodes(& m, & b, & out->pointlist, & out->pointattributelist,
                       & out->pointmarkerlist);
        }

        // Simp. always write the triangles.
        writeelements(& m, & b, & out->trianglelist, & out->triangleattributelist);

        if ( b.poly || b.convex ) {
            writepoly(& m, & b, & out->segmentlist, & out->segmentmarkerlist);
            out->numberofholes = m.holes;
            out->numberofregions = m.regions;
            if ( b.poly ) {
                out->holelist = in->holelist;
                out->regionlist = in->regionlist;
            } else {
                out->holelist = ( REAL * ) NULL;
                out->regionlist = ( REAL * ) NULL;
            }
        }
        if ( b.edgesout ) {
            writeedges(& m, & b, & out->edgelist, & out->edgemarkerlist);
        }
        // Simp. no voronoi
        if ( b.neighbors ) {
            writeneighbors(& m, & b, & out->neighborlist);
        }
        // Simp. No statistics.
        if ( b.docheck ) {
            checkmesh(& m, & b);
            checkdelaunay(& m, & b);
        }
        triangledeinit(& m, & b);
    }
Exemple #7
0
int _Cdecl my2e_parsecommandline( char *s ) {
    s[ (unsigned char)s[ 0 ] ] = '\0';
/*    printf("_my2e_parsecommandline( %s )\n", s );*/
    parsecommandline( &s[ 1 ], 1 );
    return( errorlevel );
}
Exemple #8
0
/*
 * do the prompt/input/process loop
 *
 *  If xflg is true, the function will not go interactive, but returns.
 *  If commandline != NULL, this command is processed first.
 *
 *  Return: 0: on success
 */
int process_input(int xflag, char *commandline)
{
    /* Dimensionate parsedline that no sprintf() can overflow the buffer
     */
  char parsedline[MAX_INTERNAL_COMMAND_SIZE + sizeof(errorlevel) * 8]
    , *readline;
#if 0
/* Return the maximum pointer into parsedline to add 'numbytes' bytes */
#define parsedMax(numbytes)   \
  (parsedline + MAX_INTERNAL_COMMAND_SIZE - 1 - (numbytes))
  char *evar;
  char *tp;
  char *cp;
#endif
  char *ip;
#if 0
  char forvar;
#endif
  int echothisline;
  int tracethisline;

  do
  {
#ifdef FEATURE_LONG_FILENAMES
    if( toupper( *getEnv( "LFN" ) ) == 'N' )
         __supportlfns = 0;
    else __supportlfns = 1;
#endif
  	interactive_command = 0;		/* not directly entered by user */
  	echothisline = tracethisline = 0;
    if(commandline) {
      ip = commandline;
      readline = commandline = 0;
    } else {
    if ((readline = malloc(MAX_INTERNAL_COMMAND_SIZE + 1)) == 0)
    {
      error_out_of_memory();
      return 1;
    }

      if (0 == (ip = readbatchline(&echothisline, readline,
                      MAX_INTERNAL_COMMAND_SIZE)))
      { /* if no batch input then... */
      if (xflag   /* must not go interactive */
       || (fdattr(0) & 0x84) == 0x84  /* input is NUL device */
       || feof(stdin))    /* no further input */
      {
        free(readline);
        break;
      }

      /* Go Interactive */
		interactive_command = 1;		/* directly entered by user */
		/* Ensure the prompt starts at column #0 */
		if(echo && (mywherex()>1))
			outc('\n');
      readcommand(ip = readline, MAX_INTERNAL_COMMAND_SIZE);
      tracemode = 0;          /* reset trace mode */
      }
    }

    	/* Make sure there is no left-over from last run */
    currCmdHelpScreen = 0;

    /* 
     * The question mark '?' has a double meaning:
     *	C:\> ?
     *		==> Display short help
     *
     *	C:\> ? command arguments
     *		==> enable tracemode for just this line
     */
    if(*(ip = ltrimcl(ip)) == '?') {
    	 ip = ltrimcl(ip + 1);
    	 if(!*ip) {		/* is short help command */
#ifdef INCLUDE_CMD_QUESTION
    	 	showcmds(ip);
#endif
			free(readline);
			continue;
		}
		/* this-line-tracemode */
		echothisline = 0;
		tracethisline = 1;
	}

#if 0
  /* The FOR hack
    If the line matches /^\s*for\s+\%[a-z]\s/, the FOR hack
    becomes active, because FOR requires the sequence "%<ch>"
    in its input.
    When the percent (%) expansion is made later on, any
    sequence "%<ch>" is retained.
  */
  cp = ip;
  if(matchtok(cp, "for") && *cp == '%' && isalpha(cp[1])
   && isargdelim(cp[2]))   /* activate FOR hack */
    forvar = toupper(cp[1]);
  else forvar = 0;

#else
	if(cmd_for_hackery(ip)) {
		free(readline);
		continue;
	}
#endif

	{	int rc = expandEnvVars(ip, parsedline);
		free(readline);
		if(!rc) {
			error_line_too_long();
			continue;
		}
	}
  
    if (echothisline)           /* Echo batch file line */
    {
      printprompt();
      puts(parsedline);
    }

    if (*parsedline)
    {
      if(swapOnExec != ERROR)
      	swapOnExec = defaultToSwap;
      if(tracethisline)
      	++tracemode;
      parsecommandline(parsedline, TRUE);
      if(tracethisline)
      	--tracemode;
    }
  }
  while (!canexit || !exitflag);

  return 0;
}
Exemple #9
0
int cmd_set(char *param)
{	char *value;
	char *promptBuf = 0, tempcmd[255];
	int ret;

	optC = promptUser = upCaseValue = optExecute = 0;

	if(leadOptions(&param, opt_set, 0) != E_None)
		return 1;

	switch(breakVarAssign(ctxtEnvironment, param, &value)) {
	case 1:			/* no equal sign */
#ifdef FEATURE_CMD_SET_PRINT
        if( ( value = getEnv( param ) ) != NULL ) printf( "%s\n", value );
        else {
            error_env_var_not_found( param );
            return( 1 );
        }
        return( 0 );
#else
		error_syntax(0);
		return 1;
#endif
	case 0:			/* displayed */
		return 0;
#ifdef DEBUG
	case 2: break;
	default:
		dprintf(("[SET: Invalid response from breakVarAssign()]\n"));
		return 1;
#endif
	}

	if(promptUser) {	/* -> Display the value, then read and assign */
		assert(value);
		fputs(value, stdout);
		promptBuf = malloc(promptBuffer);
		if(!promptBuf) {
			error_out_of_memory();
			return E_NoMem;
		}
		fgets(promptBuf, promptBuffer, stdin);
		if(cbreak) {
			free(promptBuf);
			return E_CBreak;
		}
		value = strchr(promptBuf, '\0');
		while(--value >= promptBuf && (*value == '\n' || *value == '\r'));
		value[1] = '\0';	/* strip trailing newlines */
		value = promptBuf;
	}
    if (optExecute) {
        char *tempfile = tmpfn();
        FILE *fhandle;

        if (!tempfile) return (1);
        sprintf (tempcmd, "%s>%s", value, tempfile);
        parsecommandline (tempcmd, TRUE);
        fhandle = fopen (tempfile, "r");
        if (!fhandle) {
            unlink (tempfile);
            free (tempfile);
            return (1);
        }
        fgets (tempcmd, 255, fhandle);
        value = strchr(tempcmd, '\n');
        if (value) *value = '\0';
        value = tempcmd;
        fclose (fhandle);
        unlink (tempfile);
        free (tempfile);
    }

	/* If the value is just blanks, it means to delete the value;
		but otherwise even leading and trailing spaces must be kept */
	if(is_empty(value))
		value = 0;

	if (upCaseValue) StrUpr(value); /* set value as upper case, eg for if testing */

	ret = chgEnvCase(optC, param, value);
	free(promptBuf);
	return ret;
}
int main (int argc, char * argv[])
{
	// Plant frequencies... (zeroed here just to suppress a -Wall warning)
	float f_AA_MM = 0;
	float f_AA_Mm = 0;
	float f_AA_mm = 0;
	float f_Aa_MM = 0;
	float f_Aa_Mm = 0;
	float f_Aa_mm = 0;
	float f_aa_MM = 0;
	float f_aa_Mm = 0;
	float f_aa_mm = 0;

	float next_f_AA_MM;
	float next_f_AA_Mm;
	float next_f_AA_mm;
	float next_f_Aa_MM;
	float next_f_Aa_Mm;
	float next_f_Aa_mm;
	float next_f_aa_MM;
	float next_f_aa_Mm;
	float next_f_aa_mm;

	// Pollen frequencies...
	float p_A_M;
	float p_A_m;
	float p_a_M;
	float p_a_m;
	
	// Egg frequencies...
	float e_A_M;
	float e_A_m;
	float e_a_M;
	float e_a_m;
	
	float male = 0;
	float female = 0;
	float inconstant = 0;
	
	float PSatC;				// Pollen saturation point for cosex receivers
	
	float K;
	float k;
	
	float totalpollen;
	float totalplants;
	int n;
	int x;
	int y;
	
	char bmp_filename[1024];
	char txt_filename[1024];
	
	FILE * textfile = NULL;

	
	parsecommandline(argc, argv);
	
	result = malloc(subdivisions * sizeof(int*));
	if (result == NULL)
	{
		printf("Out of memory!\n");
		exit(1);
	}
	for (n = 0; n < subdivisions; n++)
	{
		result[n] = malloc(subdivisions * sizeof(int));
		if (result[n] == NULL)
		{
			printf("Out of memory!\n");
			exit(1);
		}
	}
	
	// Print all settings...
	
	printf("\nModel %d\n\n", MODEL);
	
	if (onerun)
	{
		printf("Q = %G (K = %G, pi = %G)\n", Q, (1 / Q) - 1, 1 / Q);
		printf("F = %G (k = %G, \"omega\" = %G)\n\n", F, (1 / F) - 1, 1 / F);
	}
	
	printf("h = %G\n", h);
	printf("Selfing rate = %G\n", S);
	printf("Inbreeding depression = %G\n", d);
	printf("YY viability = %G (YY penalty = %G)\n", V, 1 - V);
	printf("PSatF = %G\n\n", PSatF);
	
	printf("Iterations = %d\n\n", endpoint);
	
	if (onerun == 0)
	{
		printf("Warning: --onerun option not received, therefore program will\n");
		printf("use %d Q and F combinations and produce a graph. This may\n", subdivisions * subdivisions);
		printf("take a long time. If this was not your intention, terminate now.\n\n");
		
		printf("                       %d |\n", oldformat ? oldformatlimit : 1);
		printf("Output format:       %s   |\n", oldformat ? "k" : "F");
		printf("                       0 |\n");
		printf("                          -----\n");
		printf("                          0   %d\n", oldformat ? oldformatlimit : 1);
		printf("                            %s\n\n", oldformat ? "K" : "Q");
	}
	
	// Choose names for .bmp and .txt output files (if needed)...
	
	sprintf(bmp_filename, "model%d_start%s_V%G_S%G_d%G_h%G_PSatF%G_ppY%G.bmp", MODEL, pgd ? "PGD" : "DIO", V, S, d, h, PSatF, ppY);
	sprintf(txt_filename, "model%d_start%s_V%G_S%G_d%G_h%G_PSatF%G_ppY%G.txt", MODEL, pgd ? "PGD" : "DIO", V, S, d, h, PSatF, ppY);
	
	// Open .txt output file (if needed)...
	
	if (onerun == 0 && gnuplot)
	{
		textfile = fopen(txt_filename, "w");
	}
	
	
	for (y = 0; y < subdivisions; y++)
	{
		for (x = 0; x < subdivisions; x++)
		{
			if (onerun == 0)
			{
			
				// Here we map the X,Y coordinates of our output .bmp file onto Q and F parameters...
			
				if (oldformat == 0)
				{
					Q = (float) x / (subdivisions - 1);						// X axis: Q values 0 to 1
					F = (float) y / (subdivisions - 1);						// Y axis: F values 0 to 1
				} else {
					K = ((float) x / (subdivisions - 1)) * oldformatlimit;	// X axis: K values 0 to oldformatlimit
					k = ((float) y / (subdivisions - 1)) * oldformatlimit;	// Y axis: k values 0 to oldformatlimit
					
					// But Q and F are the parameters actually used by the code, so calculate them:
					Q = 1 / (1 + K);
					F = 1 / (1 + k);
				}
			}
	
			// Set start plant frequencies...
			
			if (pgd == 0)				// Start with DIOECY, try inconstant invasion
			{
				f_AA_MM = 0;
				f_AA_Mm = 0;
				f_AA_mm = 0.499;
				f_Aa_MM = 0;
				f_Aa_Mm = 0.002;
				f_Aa_mm = 0.499;
				f_aa_MM = 0;
				f_aa_Mm = 0;
				f_aa_mm = 0;
			} else {					// Start with PSEUDO-GYNODIOECY, try male invasion
				f_AA_MM = 0.499;
				f_AA_Mm = 0;
				f_AA_mm = 0;
				f_Aa_MM = 0.499;
				f_Aa_Mm = 0;
				f_Aa_mm = 0.002;
				f_aa_MM = 0;
				f_aa_Mm = 0;
				f_aa_mm = 0;
			}
	
			for (n = 0; n < endpoint; n++)
			{
				// Outcrossed pollen frequencies....................................................
				//
				// Here we sum up the 4 types of pollen (containing the 4 possible allele combinations)
				// from the various possible sources. We could do this in 4 equations (as in the paper)
				// but it's simpler to consider each source in turn and add to the totals.
				
				p_A_M = 0;
				p_A_m = 0;
				p_a_M = 0;
				p_a_m = 0;
				
				// From AA MM pure females (genotype 1)
				;
				
				// From AA Mm pure females (genotype 2)
				;
				
				// From AA mm pure females (genotype 3)
				;
				
				// From Aa MM inconstants (genotype 4) as cosexes
				p_A_M += f_Aa_MM * 0.5 * h * Q;
				p_a_M += f_Aa_MM * 0.5 * h * Q;
				
				// From Aa MM inconstants (genotype 4) as males
				p_A_M += f_Aa_MM * 0.5 * (1 - h);
				p_a_M += f_Aa_MM * 0.5 * (1 - h);
				
				// From Aa Mm inconstants (genotype 5) as cosexes
				p_A_M += f_Aa_Mm * 0.25 * h * Q;
				p_A_m += f_Aa_Mm * 0.25 * h * Q;
				p_a_M += f_Aa_Mm * 0.25 * h * Q;
				p_a_m += f_Aa_Mm * 0.25 * h * Q;
				
				// From Aa Mm inconstants (genotype 5) as males
				p_A_M += f_Aa_Mm * 0.25 * (1 - h);
				p_A_m += f_Aa_Mm * 0.25 * (1 - h);
				p_a_M += f_Aa_Mm * 0.25 * (1 - h);
				p_a_m += f_Aa_Mm * 0.25 * (1 - h);
				
				// From Aa mm pure males (genotype 6)
				p_A_m += f_Aa_mm * 0.5;
				p_a_m += f_Aa_mm * 0.5;
				
				// From aa MM inconstants (genotype 7) as cosexes
				p_a_M += f_aa_MM * h * Q;
				
				// From aa MM inconstants (genotype 7) as males
				p_a_M += f_aa_MM * (1 - h);
				
				// From aa Mm inconstants (genotype 8) as cosexes
				p_a_M += f_aa_Mm * 0.5 * h * Q;
				p_a_m += f_aa_Mm * 0.5 * h * Q;
				
				// From aa Mm inconstants (genotype 8) as males
				p_a_M += f_aa_Mm * 0.5 * (1 - h);
				p_a_m += f_aa_Mm * 0.5 * (1 - h);
				
				// From aa mm pure males (genotype 9)
				p_a_m += f_aa_mm;
				
				// Normalise pollen frequencies to add up to 1......................................
				
				totalpollen = p_A_M + p_A_m + p_a_M + p_a_m;
				if (totalpollen > 0)
				{
					p_A_M /= totalpollen;
					p_A_m /= totalpollen;
					p_a_M /= totalpollen;
					p_a_m /= totalpollen;
				}
				
				// Outcrossed egg frequencies.......................................................
				
				// Calculate pollen required to fertilise a cosex's outcrossing ovules:
				PSatC = PSatF * F * (1 - S);
				
				e_A_M = 0;
				e_A_m = 0;
				e_a_M = 0;
				e_a_m = 0;
				
				// From AA MM pure females (genotype 1)
				if (totalpollen >= PSatF)
				{
					e_A_M += f_AA_MM;
				} else {
					e_A_M += f_AA_MM * totalpollen / PSatF;
				}
				
				// From AA Mm pure females (genotype 2)
				if (totalpollen >= PSatF)
				{
					e_A_M += f_AA_Mm * 0.5;
					e_A_m += f_AA_Mm * 0.5;
				} else {
					e_A_M += f_AA_Mm * 0.5 * totalpollen / PSatF;
					e_A_m += f_AA_Mm * 0.5 * totalpollen / PSatF;
				}
				
				// From AA mm pure females (genotype 3)
				if (totalpollen >= PSatF)
				{
					e_A_m += f_AA_mm;
				} else {
					e_A_m += f_AA_mm * totalpollen / PSatF;
				}
				
				// From Aa MM inconstants (genotype 4) as cosexes
				if (totalpollen >= PSatC)
				{
					e_A_M += f_Aa_MM * h * 0.5 * (1 - S) * F;
					e_a_M += f_Aa_MM * h * 0.5 * (1 - S) * F;
				} else {
					e_A_M += f_Aa_MM * h * 0.5 * (1 - S) * F * totalpollen / PSatC;
					e_a_M += f_Aa_MM * h * 0.5 * (1 - S) * F * totalpollen / PSatC;
				}
				
				// From Aa Mm inconstants (genotype 5) as cosexes
				if (totalpollen >= PSatC)
				{
					e_A_M += f_Aa_Mm * h * 0.25 * (1 - S) * F;
					e_A_m += f_Aa_Mm * h * 0.25 * (1 - S) * F;
					e_a_M += f_Aa_Mm * h * 0.25 * (1 - S) * F;
					e_a_m += f_Aa_Mm * h * 0.25 * (1 - S) * F;
				} else {
					e_A_M += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC;
					e_A_m += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC;
					e_a_M += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC;
					e_a_m += f_Aa_Mm * h * 0.25 * (1 - S) * F * totalpollen / PSatC;
				}
				
				// From Aa mm pure males (genotype 6)
				;
				
				// From aa MM inconstants (genotype 7) as cosexes
				if (totalpollen >= PSatC)
				{
					e_a_M += f_aa_MM * h * (1 - S) * F;
				} else {
					e_a_M += f_aa_MM * h * (1 - S) * F * totalpollen / PSatC;
				}
				
				// From aa Mm inconstants (genotype 8) as cosexes
				if (totalpollen >= PSatC)
				{
					e_a_M += f_aa_Mm * h * 0.5 * (1 - S) * F;
					e_a_m += f_aa_Mm * h * 0.5 * (1 - S) * F;
				} else {
					e_a_M += f_aa_Mm * h * 0.5 * (1 - S) * F * totalpollen / PSatC;
					e_a_m += f_aa_Mm * h * 0.5 * (1 - S) * F * totalpollen / PSatC;
				}
				
				// From aa mm pure males (genotype 9)
				;
				
				// WE CANNOT AND MUST NOT NORMALISE THE EGG FREQUENCIES, AS WE HAVEN'T
				// YET CONSIDERED THE SELFED EGGS. BUT WE DON'T NEED TO NORMALISE.
				
				// Plant frequencies from outcrossing...............................................
				
				next_f_AA_MM = p_A_M * e_A_M;
				next_f_AA_Mm = p_A_M * e_A_m + p_A_m * e_A_M;
				next_f_AA_mm = p_A_m * e_A_m;
				next_f_Aa_MM = p_A_M * e_a_M + p_a_M * e_A_M;
				next_f_Aa_Mm = p_A_M * e_a_m + p_A_m * e_a_M + p_a_M * e_A_m + p_a_m * e_A_M;
				next_f_Aa_mm = p_A_m * e_a_m + p_a_m * e_A_m;
				next_f_aa_MM = p_a_M * e_a_M;
				next_f_aa_Mm = p_a_M * e_a_m + p_a_m * e_a_M;
				next_f_aa_mm = p_a_m * e_a_m;
				
				// Additional plants from selfing...................................................
				
				// From AA MM pure females (genotype 1)
				;
				
				// From AA Mm pure females (genotype 2)
				;
				
				// From AA mm pure females (genotype 3)
				;
				
				// From Aa MM inconstants (genotype 4)
				next_f_AA_MM += f_Aa_MM * 0.25 * S * (1 - d) * h * F;
				next_f_Aa_MM += f_Aa_MM * 0.5 * S * (1 - d) * h * F;
				next_f_aa_MM += f_Aa_MM * 0.25 * S * (1 - d) * h * F;
				
				// From Aa Mm inconstants (genotype 5)
				next_f_AA_MM += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F;
				next_f_AA_Mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F;
				next_f_AA_mm += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F;
				next_f_Aa_MM += f_Aa_Mm * 0.125 * S * (1 - d) * h * F;
				next_f_Aa_Mm += f_Aa_Mm * 0.25 * S * (1 - d) * h * F;
				next_f_Aa_mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F;
				next_f_aa_MM += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F;
				next_f_aa_Mm += f_Aa_Mm * 0.125 * S * (1 - d) * h * F;
				next_f_aa_mm += f_Aa_Mm * 0.0625 * S * (1 - d) * h * F;
				
				// From Aa mm pure males (genotype 6)
				;
				
				// From aa MM inconstants (genotype 7)
				next_f_aa_MM += f_aa_MM * S * (1 - d) * h * F;
				
				// From aa Mm inconstants (genotype 8)
				next_f_aa_MM += f_aa_Mm * 0.25 * S * (1 - d) * h * F;
				next_f_aa_Mm += f_aa_Mm * 0.5 * S * (1 - d) * h * F;
				next_f_aa_mm += f_aa_Mm * 0.25 * S * (1 - d) * h * F;
				
				// From aa mm pure males (genotype 9)
				;

				// Apply YY penalty.................................................................
				
				next_f_aa_MM *= V;
				next_f_aa_Mm *= V;
				next_f_aa_mm *= V;
				
				// Copy.............................................................................
				
				f_AA_MM = next_f_AA_MM;
				f_AA_Mm = next_f_AA_Mm;
				f_AA_mm = next_f_AA_mm;
				f_Aa_MM = next_f_Aa_MM;
				f_Aa_Mm = next_f_Aa_Mm;
				f_Aa_mm = next_f_Aa_mm;
				f_aa_MM = next_f_aa_MM;
				f_aa_Mm = next_f_aa_Mm;
				f_aa_mm = next_f_aa_mm;
			
				// Normalise plant frequencies to add up to 1.......................................
				
				totalplants = f_AA_MM + f_AA_Mm + f_AA_mm + f_Aa_MM + f_Aa_Mm + f_Aa_mm + f_aa_MM + f_aa_Mm + f_aa_mm;
				if (totalplants > 0)
				{
					f_AA_MM /= totalplants;
					f_AA_Mm /= totalplants;
					f_AA_mm /= totalplants;
					f_Aa_MM /= totalplants;
					f_Aa_Mm /= totalplants;
					f_Aa_mm /= totalplants;
					f_aa_MM /= totalplants;
					f_aa_Mm /= totalplants;
					f_aa_mm /= totalplants;
				}
			}
	
			// Calculate and save results...
			
			female = f_AA_MM + f_AA_Mm + f_AA_mm;
			male = f_Aa_mm + f_aa_mm;
			inconstant = f_Aa_MM + f_Aa_Mm + f_aa_MM + f_aa_Mm;
			
			if (male > threshold && female > threshold && inconstant > threshold)
			{
				result[x][y] = SSD;
			} else if (male > threshold && female > threshold) {
				result[x][y] = DIO;
			} else if (female > threshold && inconstant > threshold) {
				result[x][y] = PGD;
			} else if (male > threshold && inconstant > threshold) {
				result[x][y] = PAD;
			} else if (inconstant > threshold) {
				result[x][y] = INC;
			} else {
				result[x][y] = 0;
			}
			
			if (onerun == 0 && gnuplot)
			{
				fprintf(textfile, "%f", female);
				if (x == subdivisions - 1)
				{
					fprintf(textfile, "\n");
				} else {
					fprintf(textfile, "\t");
				}
			}
			
			if (onerun) break;
		}
		if (onerun) break;
	}
	
	if (onerun == 0)
	{
		drawbmp(bmp_filename, 1);
		printf("Saved %s\n", bmp_filename);
	} else {
		printf("Females       Males         Inconstants\n");
		printf("%.6f      %.6f      %.6f\n\n", female, male, inconstant);

		printf("Genotype frequencies, as notated by E&B (2007), or C&C (2012):\n\n");
		
		printf("E&B:  AA MM     AA Mm     AA mm     Aa MM     Aa Mm     Aa mm     aa MM     aa Mm     aa mm\n");
		printf("C&C:  mm AA     mm Aa     mm aa     Mm AA     Mm Aa     Mm aa     MM AA     MM Aa     MM aa\n");
		printf("      %.6f  %.6f  %.6f  %.6f  %.6f  %.6f  %.6f  %.6f  %.6f\n\n", f_AA_MM, f_AA_Mm, f_AA_mm, f_Aa_MM, f_Aa_Mm, f_Aa_mm, f_aa_MM, f_aa_Mm, f_aa_mm);
		
		if (male > threshold && female > threshold && inconstant > threshold)
		{
			printf("Final state: SSD\n");
		} else if (male > threshold && female > threshold) {
			printf("Final state: DIO\n");
		} else if (female > threshold && inconstant > threshold) {
			printf("Final state: PGD\n");
		} else if (male > threshold && inconstant > threshold) {
			printf("Final state: PAD\n");
		} else if (inconstant > threshold) {
			printf("Final state: INC\n");
		} else {
			printf("Final state: ???\n");
		}
	}
	
	return 0;
}