Exemple #1
0
bool Plan_File::Read_Plan_Def (void) 
{
	char *str_ptr, filename [FILE_NAME_SIZE], buffer [FIELD_BUFFER];
	FILE *def;

	//---- construct the definition filename ----

	str_cpy (filename, sizeof (filename)-5, Filename ());
	str_cat (filename, sizeof (filename), ".def");

	//---- open the definition file ----

	def = f_open (filename, "rt");

	if (def == NULL) return (false);

	//---- get the header line ----

	if (fgets (filename, sizeof (filename), def) == NULL) return (Status (DEF_FORMAT));

	if (str_cmp (filename, "AECOM HEADER", 12) != 0) return (Status (DEF_FORMAT));

	str_ptr = filename + 12;

	str_ptr = Get_Token (str_ptr, buffer);

	File_Format (buffer);

	if (str_cmp (buffer, "BINARY", 6) != 0 && str_cmp (buffer, "VERSION3", 8) != 0) {
		return (Status (DEF_FORMAT));
	}
	str_ptr = Get_Token (str_ptr, buffer);

	int scale = atoi (buffer);
	if (scale < 2 || scale > 100) return (Status (DEF_FORMAT));
	if (Traveler_Scale () < scale) {
		exe->Error ("Traveler Scaling Factor %d does not match Plan File Factor %d", Traveler_Scale (), scale);
	}
	Traveler_Scale (scale);

	str_ptr = Get_Token (str_ptr, buffer);

	if (str_cmp (buffer, "NODE_BASED", 10) == 0) {
		Node_Based_Flag (true);
	} else if (str_cmp (buffer, "LINK_BASED", 10) == 0) {
		Node_Based_Flag (false);
	} else {
		return (Status (DEF_FORMAT));
	}
	fclose (def);
	return (true);
}
Exemple #2
0
bool User_Program::Compile (string &text, bool list_flag)
{
	Strings lines;
	Str_Itr line_itr;

	//---- split the text into lines ----

	String_Ptr (text)->Parse (lines, "\n\r\f");

	for (line_itr = lines.begin (); line_itr != lines.end (); line_itr++) {
		line_num++;

		if (list_flag) {
			exe->Print (1, "\t") << *line_itr;
		}
		line_itr->Clean ();
		if (line_itr->empty ()) continue;

		if (declare_flag) {
			if (!Initial_Declare (*line_itr)) break;
		} else if (table_flag) {
			if (!Initial_Table (*line_itr)) break;
		} else {
			while (Get_Token (*line_itr)) {
				if (!Process_Token ()) break;
			}
		}
	}
	return (true);
}
Exemple #3
0
/*************************************************************************
 *
 *  Parse_Proc_Decl() - The "proc" declaration keyword has just
 *  been parsed. Create Proc structure and add name to symbol table.
 *  Get parameter LVALUES and add them to proc's local symbol table.
 *  Get the block of text that makes up the procedure body and save
 *  a pointer to it in the Proc struct.
 *
 ************************************************************************/
void Parse_Proc_Decl(int type)
{
	Proc *proc;

	if(Get_Token() != TK_STRING)
		Err_Unknown(type, "identifier", NULL);

	/* Allocate and initialize a Proc struct... */
	proc = New_User_Proc();

	/* Enter proc's name in symbol table. */
	Add_Symbol(token_buffer, proc, DECL_PROC);

	cur_proc = proc;
	Push_Local_Symbols();
	proc_nest_level++;

	/* Get parameter declarations... */
	Compile_Proc_Params_Decl(proc);

	/* Get body... */
	proc->block = Parse_Block("proc");

	Pop_Local_Symbols();
	proc_nest_level--;
	cur_proc = NULL;

} /* end of Parse_Proc_Decl() */
int Input_Process(char *input,int *tokens,int *error)

{
	int start,end;
	end=start=0;	
	while(input[end]!='\0')
	{
		//if the first character is punct then break.
		if(ispunct(input[end])&&end==0)
		{
			*error=-1;
			printf("You can't start with these thing instead of words.\n");
			return -1;
		}
		if(ispunct(input[end])&&input[end]!='-')
			return -1;			
		Get_Token(input,&start,&end,&(*error));
		if(*error==-1)
			return -1;
		//if the input doesn't have a match with the vocabulary then break.
		Extract_Tokens(input,start,end,tokens,&(*error));
		if(*error==-1)
			return -1;
	}
	return 0;
}
TOKEN expr_get_token()
{
	Get_Token();

	if(Token.Function_Id == X_TOKEN)
		return FLOAT_ID_TOKEN;
	else if(Token.Function_Id == Y_TOKEN)
		return FLOAT_ID_TOKEN;
	else if(Token.Function_Id == Z_TOKEN)
		return FLOAT_ID_TOKEN;
	else if(Token.Function_Id == U_TOKEN)
		return FLOAT_ID_TOKEN;
	else if(Token.Function_Id == V_TOKEN)
		return FLOAT_ID_TOKEN;
	else if(Token.Function_Id == IDENTIFIER_TOKEN)
		return FLOAT_ID_TOKEN;
	else if(Token.Function_Id == CLOCK_TOKEN)
	{
		Token.Token_Float = opts.FrameSeq.Clock_Value;
		return FLOAT_TOKEN;
	}
	else if(Token.Function_Id == PI_TOKEN)
	{
		Token.Token_Float = M_PI;
		return FLOAT_TOKEN;
	}
	else if(Token.Function_Id == RED_TOKEN)
		return RED_TOKEN;
	else if(Token.Function_Id == GREEN_TOKEN)
		return GREEN_TOKEN;
	else if(Token.Function_Id == BLUE_TOKEN)
		return BLUE_TOKEN;
	else if(Token.Function_Id == FILTER_TOKEN)
		return FILTER_TOKEN;
	else if(Token.Function_Id == TRANSMIT_TOKEN)
		return TRANSMIT_TOKEN;
	else if(Token.Function_Id == T_TOKEN)
		return T_TOKEN;
	else if(Token.Function_Id == GRAY_TOKEN)
		return GRAY_TOKEN;

	if(Token.Token_Id == FLOAT_FUNCT_TOKEN)
	{
		if(Token.Function_Id == FLOAT_TOKEN)
			return FLOAT_TOKEN;
		else if(Token.Function_Id == FLOAT_ID_TOKEN)
		{
			Token.Token_Float = *((DBL *)Token.Data);
			return FLOAT_TOKEN;
		}

		return FUNCT_ID_TOKEN;
	}

	return Token.Token_Id;
}
Exemple #6
0
TOKEN Parser::expr_get_token()
{
    Get_Token();

    if(Token.Function_Id == X_TOKEN)
        return FLOAT_ID_TOKEN;
    else if(Token.Function_Id == Y_TOKEN)
        return FLOAT_ID_TOKEN;
    else if(Token.Function_Id == Z_TOKEN)
        return FLOAT_ID_TOKEN;
    else if(Token.Function_Id == U_TOKEN)
        return FLOAT_ID_TOKEN;
    else if(Token.Function_Id == V_TOKEN)
        return FLOAT_ID_TOKEN;
    else if(Token.Function_Id == IDENTIFIER_TOKEN)
        return FLOAT_ID_TOKEN;
    else if(Token.Function_Id == CLOCK_TOKEN)
    {
        Token.Token_Float = clockValue;
        return FLOAT_TOKEN;
    }
    else if(Token.Function_Id == PI_TOKEN)
    {
        Token.Token_Float = M_PI;
        return FLOAT_TOKEN;
    }
    else if(Token.Function_Id == RED_TOKEN)
        return RED_TOKEN;
    else if(Token.Function_Id == GREEN_TOKEN)
        return GREEN_TOKEN;
    else if(Token.Function_Id == BLUE_TOKEN)
        return BLUE_TOKEN;
    else if(Token.Function_Id == FILTER_TOKEN)
        return FILTER_TOKEN;
    else if(Token.Function_Id == TRANSMIT_TOKEN)
        return TRANSMIT_TOKEN;
    else if(Token.Function_Id == T_TOKEN)
        return T_TOKEN;
    else if(Token.Function_Id == GRAY_TOKEN)
        return GRAY_TOKEN;

    if(Token.Token_Id == FLOAT_FUNCT_TOKEN)
    {
        if(Token.Function_Id == FLOAT_TOKEN)
            return FLOAT_TOKEN;
        else if(Token.Function_Id == FLOAT_ID_TOKEN)
        {
            Token.Token_Float = *(reinterpret_cast<DBL *>(Token.Data));
            return FLOAT_TOKEN;
        }

        return FUNCT_ID_TOKEN;
    }

    return Token.Token_Id;
}
Exemple #7
0
bool Time_Range::Add_Ranges (char *ranges)
{
	int low, high, periods;
	char *ptr;

	periods = (period_flag) ? increment : 0;

	//---- check for special conditions ----

	if (ranges == NULL || *ranges == '\0' || *ranges == '\n') return (true);
	
	if (str_cmp (ranges, "All") == 0) {
		high = (period_flag) ? Step (MIDNIGHT) : MAX_INTEGER;

		return (Add_Range (0, high-1, periods));
	}

	//---- unpack the range string ----	

	while (ranges != NULL && *ranges != '\0' && *ranges != '\n') {

		ranges = Get_Token (ranges, buffer, sizeof (buffer));

		if (buffer [0] == '\0') break;

		ptr = strchr (buffer, '.');

		if (ptr == NULL) goto range_error;

		if (*(ptr+1) == '.') {
			*ptr++ = '\0';
		} else {
			ptr = strchr (ptr+1, '.');

			if (ptr == NULL || *(ptr+1) != '.') goto range_error;

			*ptr++ = '\0';
		}
		low = Step (buffer);

		while (*ptr == '.') ptr++;

		high = Step (ptr);

		if (!Add_Range (low, high-1, periods)) return (false);
	}
	return (Num_Ranges () > 0);

range_error:
	if (Send_Messages ()) {
		exe->Error ("Range Value (..) is Missing from Time Range %s", buffer);
	}
	return (false);
}
Exemple #8
0
bool Time_Range::Add_Breaks (char *breaks)
{
	int low, high;
	char *ptr;

	//---- check for special conditions ----

	if (breaks == NULL || *breaks == '\0' || *breaks == '\n') return (true);

	if (str_cmp (breaks, "None") == 0) {
		return (Add_Range (0, Step (MIDNIGHT)-1));
	}

	//---- unpack the break string ----	

	low = 0;

	while (breaks != NULL && *breaks != '\0' && *breaks != '\n') {

		breaks = Get_Token (breaks, buffer, sizeof (buffer));

		if (buffer [0] == '\0') break;

		ptr = strchr (buffer, '.');
		if (ptr != NULL && *(ptr+1) == '.') goto break_error;

		high = Step (buffer);

		if (low > high) goto break_error;

		if (low < high) {
			if (!Add_Range (low, high-1)) return (false);
		}
		low = high;
	}
	high = Step (MIDNIGHT);

	if (low < high) {
		return (Add_Range (low, high-1));
	}
	return (Num_Ranges () > 0);

break_error:
	if (Send_Messages ()) {
		exe->Error ("Range Breaks %s are Illogical", breaks);
	}
	return (false);
}
Exemple #9
0
bool Time_Range::Add_Label (char *label)
{
	int low, high, periods;
	char *ptr;

	periods = (period_flag) ? increment : 0;

	//---- check for special conditions ----

	if (label == NULL || *label == '\0' || *label == '\n') return (true);

	//---- unpack the label string ----	

	Get_Token (label, buffer, sizeof (buffer));

	if (buffer [0] == '\0') return (false);

	ptr = strchr (buffer, '_');

	if (ptr == NULL) {
		ptr = strstr (buffer, "..");
		if (ptr == NULL) goto label_error;
		*ptr++ = '\0';
	}
	*ptr++ = '\0';

	low = Time_Label (buffer);

	high = Time_Label (ptr);

	return (Add_Range (low, high-1, periods));

label_error:
	if (Send_Messages ()) {
		exe->Error ("Label Value is Missing from Time Label %s", buffer);
	}
	return (false);
}
Exemple #10
0
PARAMS *CompileExtrudeParams(void)
{
  PARAMS *plist, *p;
  int cnt, token;

  /* The first param will hold the vertex count. */
	plist = p = New_Param();
  /* Get the vertex list... */
  cnt = 0;
  while(Get_Token() == TK_VERTEX)
  {
    /*
		 * Get vertex, optional normal, optional color, and
		 * optional UV coordinates.
		 */
    p->next = Compile_Params("VO,VO,VO,F,F");
    while(p->next != NULL)
      p = p->next;
    cnt++;
  }
  Unget_Token();
	/* Now that we have a vertex count, put it in the first parameter. */
	plist->V.x = (double)cnt;
  if(cnt < 2)
  {
    SCN_Message(SCN_MSG_ERROR, "extrude: I need at least 2 vertices.");
    return plist;
  }

	/* Get the segments... */
	cnt = 0;
  while((token = Get_Token()) == TK_SEGMENT)
  {
		(void)Expect(TK_LEFTBRACE, "{", "segment");
		if(scn_error_cnt)
			break;
		p->next = New_Param();
		p = p->next;
		p->type = TK_SEGMENT;
	  for(token = Get_Token();
		   (token != TK_RIGHTBRACE) && (scn_error_cnt == 0);
			 token = Get_Token())
		{
			switch(token)
			{
  		/*
			 * Since we know that there is always one vector parameter for all
			 * of the transform cases, the "TK_VECTOR" type param will be
			 * aliased as the transform param. When the param list is
			 * executed we'll just just change the type back to TK_VECTOR
			 * before passing it Eval_Params().
			 * This shortcut helps keep the parameter list short.
			 */
				case TK_ROTATE:
				case TK_SCALE:
				case TK_SHEAR:
				case TK_TRANSLATE:
					p->next = Compile_Params("V");
					p = p->next;
					p->type = token;
					break;
				case TK_REPEAT:
					p->next = Compile_Params("F");
					p = p->next;
					p->type = token;
					break;
				default:
					Err_Unknown(token, NULL, "segment");
					break;
			}
		}
		/* Add end of segment marker. */
		p->next = New_Param();
		p = p->next;
		p->type = TK_RIGHTBRACE;
		cnt++;
	}
	if(token == TK_SMOOTH)
	{
		p->next = New_Param();
		p = p->next;
		p->type = TK_SMOOTH;
	}
	else
		Unget_Token();
	
  if(cnt < 1)
  {
    SCN_Message(SCN_MSG_ERROR, "extrude: I need at least 1 segment.");
    return plist;
  }

  return plist;
}
Exemple #11
0
bool Plan_File::Read (long offset)
{
	//---- check the file status ----

	if (!Check_File ()) return (false);
	if (plan == NULL) return (Status (RECORD_SIZE));
	if (File_Access () != READ) return (Status (ERROR));

	//---- move to a specified location in the file ----

	if (offset >= 0) {
		if (!Offset (offset)) return (false);
	}

	//---- allocate space ----

	if (allocate_memory) {
		if (!Setup_Record ()) return (false);
	}

	//---- read the next plan ----

	if (Record_Format () == BINARY) {
		int num_token;

		if (!Db_File::Read (plan, (sizeof (Plan_Data) - sizeof (int)))) return (false);

		if (time_sort) {
			int temp = plan->key1;
			plan->key1 = plan->key2;
			plan->key2 = temp;
		}
		num_record++;
		num_plan++;

		if (Leg () == 2) {
			num_trip++;
		} else if (Leg () == 1 && Trip () == 1) {
			num_traveler++;
		}
		num_token = Tokens ();
		if (num_token > 0) {
			if (!Check_Size (num_token)) return (false);
			if (!Db_File::Read (&(plan->data [0]), num_token * sizeof (int))) return (Status (PLAN_FIELDS));

			num_record++;
		}
		return (true);
	} else {

		int field, max_field, value;
		char buffer [40], *ptr;

		field = max_field = 0;

		while (Db_File::Read ()) {
			num_record++;

			ptr = Clean_Record ();

			//---- check for a blank record ----

			if (ptr == NULL || *ptr == '\0') continue;

			//---- process the plan record ----

			while (ptr != NULL) {
				ptr = Get_Token (ptr, buffer, sizeof (buffer));

				if (buffer [0] == '\0') break;
				field++;
				value = atol (buffer);

				switch (field) {
					case 1:		//---- traveler id ----
						Traveler (value);
						num_plan++;
						break;
					case 2:		//---- user field ----
						break;
					case 3:		//---- trip id ----
						Trip (value);
						break;
					case 4:		//---- leg id ----
						Leg (value);
						if (value == 2) {
							num_trip++;
						} else if (value == 1 && Trip () == 1) {
							num_traveler++;
						}
						break;
					case 5:		//---- time ----
						Time (value);
						break;
					case 6:		//---- start id ----
						Start_ID (value);
						break;
					case 7:		//---- start type ----
						Start_Type (value);
						break;
					case 8:		//---- end id ----
						End_ID (value);
						break;
					case 9:		//---- end type ----
						End_Type (value);
						break;
					case 10:	//---- duration ----
						Duration (value);
						break;
					case 11:	//---- stop time ----
						Stop_Time (value);
						break;
					case 12:	//---- max time flag ----
						break;
					case 13:	//---- cost ----
						Cost (value);
						break;
					case 14:	//---- gcf ----
						GCF (value);
						break;
					case 15:	//---- driver flag ----
						Driver_Flag (value);
						break;
					case 16:	//---- mode ----
						Mode (value);
						break;
					case 17:	//---- number of tokens ----
						if (value < 0) {
							Status (PLAN_FIELDS);
							return (false);
						}
						Tokens (value);
						max_field = value + 17;

						if (value == 0) return (true);
						if (!Check_Size (value)) return (false);
						break;

					default:	//---- token value ----

						if (field > max_field) {
							Status (PLAN_FIELDS);
							return (false);
						}
						plan->data [field - 18] = value;

						if (field == max_field) return (true);
						break;
				}
			}
		}
		if (field != 0) {
			return (Status (PLAN_FIELDS));
		}
		return (false);
	}
}
Exemple #12
0
FUNCTION_PTR Parser::Parse_DeclareFunction(int *token_id, const char *fn_name, bool is_local)
{
	FUNCTION_PTR ptr = (FUNCTION_PTR)POV_MALLOC(sizeof(FUNCTION), "Function ID");
	ExprNode *expression = NULL;
	FunctionCode function;

	// default type is float function
	*token_id = FUNCT_ID_TOKEN;

	FNCode f(this, &function, is_local, fn_name);
	f.Parameter();

	Parse_Begin();

	Get_Token();
	if(Token.Token_Id == INTERNAL_TOKEN)
	{
		GET(LEFT_PAREN_TOKEN);

		Get_Token();
		if(Token.Function_Id != FLOAT_TOKEN)
			Expectation_Error("internal function identifier");
		expression = FNSyntax_GetTrapExpression((unsigned int)(Token.Token_Float));

		function.flags = FN_INLINE_FLAG;

		GET(RIGHT_PAREN_TOKEN);
	}
	else if(Token.Token_Id == TRANSFORM_TOKEN)
	{
		if(function.parameter_cnt != 0)
			Error("Function parameters for transform functions are not allowed.");

		expression = FNSyntax_GetTrapExpression(1); // 1 refers to POVFPU_TrapSTable[1] = f_transform [trf]

		function.private_copy_method = (FNCODE_PRIVATE_COPY_METHOD)Copy_Transform;
		function.private_destroy_method = (FNCODE_PRIVATE_DESTROY_METHOD)Destroy_Transform;

		function.private_data = reinterpret_cast<void *>(Parse_Transform_Block());

		function.return_size = 3; // returns a 3d vector!!!

		// function type is vector function
		*token_id = VECTFUNCT_ID_TOKEN;
	}
	else if(Token.Token_Id == SPLINE_TOKEN)
	{
		if(function.parameter_cnt != 0)
			Error("Function parameters for spline functions are not allowed.");

		Experimental_Flag |= EF_SPLINE;

		expression = FNSyntax_GetTrapExpression(2); // 2 refers to POVFPU_TrapSTable[2] = f_spline [trf]

		function.private_copy_method = (FNCODE_PRIVATE_COPY_METHOD)Copy_Spline;
		function.private_destroy_method = (FNCODE_PRIVATE_DESTROY_METHOD)Destroy_Spline;

		Parse_Begin();
		function.private_data = reinterpret_cast<void *>(Parse_Spline());
		Parse_End();

		function.return_size = (reinterpret_cast<SPLINE *>(function.private_data))->Terms; // returns a 2d, 3d, 4d or 5d vector!!!

		// function type is vector function
		*token_id = VECTFUNCT_ID_TOKEN;
	}
	else if(Token.Token_Id == PIGMENT_TOKEN)
	{
		if(function.parameter_cnt != 0)
			Error("Function parameters for pigment functions are not allowed.");

		expression = FNSyntax_GetTrapExpression(0); // 0 refers to POVFPU_TrapSTable[0] = f_pigment [trf]

		function.private_copy_method = (FNCODE_PRIVATE_COPY_METHOD)Copy_Pigment;
		function.private_destroy_method = (FNCODE_PRIVATE_DESTROY_METHOD)Destroy_Pigment;

		Parse_Begin();
		function.private_data = reinterpret_cast<void *>(Create_Pigment());
		Parse_Pigment(reinterpret_cast<PIGMENT **>(&function.private_data));
		Parse_End();
		Post_Pigment(reinterpret_cast<PIGMENT *>(function.private_data));

		function.return_size = 5; // returns a color!!!

		// function type is vector function
		*token_id = VECTFUNCT_ID_TOKEN;
	}
	else if(Token.Token_Id == PATTERN_TOKEN)
	{
		if(function.parameter_cnt != 0)
			Error("Function parameters for pattern functions are not allowed.");

		expression = FNSyntax_GetTrapExpression(77); // 77 refers to POVFPU_TrapTable[77] = f_pattern [trf]

		function.private_copy_method = (FNCODE_PRIVATE_COPY_METHOD)Copy_Pigment;
		function.private_destroy_method = (FNCODE_PRIVATE_DESTROY_METHOD)Destroy_Pigment;

		Parse_Begin();
		function.private_data = reinterpret_cast<void *>(Create_Pigment()); // Yes, this is a pigment! [trf]
		Parse_PatternFunction(reinterpret_cast<TPATTERN *>(function.private_data));
		Parse_End();
		Post_Pigment(reinterpret_cast<PIGMENT *>(function.private_data));
	}
	else if(Token.Token_Id == STRING_LITERAL_TOKEN)
	{
		f.SetFlag(2, Token.Token_String);
		Get_Token();
		if(Token.Token_Id == COMMA_TOKEN)
		{
			Get_Token();
			if(Token.Token_Id != STRING_LITERAL_TOKEN)
				Expectation_Error("valid function expression");
			f.SetFlag(1, Token.Token_String);
		}
		else
		{
			Unget_Token();
			expression = FNSyntax_ParseExpression();
		}
	}
	else
	{
		Unget_Token();
		expression = FNSyntax_ParseExpression();
	}

	f.Compile(expression);
	FNSyntax_DeleteExpression(expression);

	Parse_End();

	*ptr = sceneData->functionVM->AddFunction(&function);

	return ptr;
}
Exemple #13
0
bool Equation_Array::Add_Equation (int type, char *parameters)
{
	static char *eq_text [] = {"BPR", "BPR_PLUS", "EXPONENTIAL", "CONICAL", "AKCELIK", "BPR+", "EXP", "CON", NULL};
	static Equation_Type eq_map [] = { BPR, BPR_PLUS, EXP, CONICAL, AKCELIK, BPR_PLUS, EXP, CONICAL };

	Equation *eq_ptr = (Equation *) Record (type);

	if (eq_ptr == NULL) return (false);

	if (parameters != NULL) {
		int i;
		char buffer [FIELD_BUFFER];

		parameters = Get_Token (parameters, buffer);

		for (i=0; eq_text [i] != NULL; i++) {
			if (str_cmp (buffer, eq_text [i]) == 0) {
				eq_ptr->type = eq_map [i];
				break;
			}
		}
		if (eq_text [i] == NULL) {
			if (Send_Messages ()) {
				exe->Error ("Unrecognized Equation Type = %s", buffer);
			}
			return (false);
		}
		parameters = Get_Double (parameters, &(eq_ptr->a));
		parameters = Get_Double (parameters, &(eq_ptr->b));
		parameters = Get_Double (parameters, &(eq_ptr->c));
		parameters = Get_Double (parameters, &(eq_ptr->d));

		if (eq_ptr->type == BPR || eq_ptr->type == BPR_PLUS) {
			if (eq_ptr->a < 0.01 || eq_ptr->b < 1.0 || eq_ptr->c < 0.4) {
				if (Send_Messages ()) {
					exe->Error ("BPR Equation Parameters %.2lf, %.2lf, %.2lf are Out of Range", eq_ptr->a, eq_ptr->b, eq_ptr->c);
				}
				return (false);
			}
			if (eq_ptr->type == BPR_PLUS) {
				if (eq_ptr->d <= 0.0) eq_ptr->d = 1.0;
				if (eq_ptr->d > 7.0) {
					if (Send_Messages ()) {
						exe->Error ("BPR Plus Equation Minimum Speed %.2lf is Out of Range", eq_ptr->d);
					}
					return (false);
				}
			}
		} else if (eq_ptr->type == EXP) {
			if (eq_ptr->a < 0.07 || eq_ptr->a > 7.5 || eq_ptr->b < 1.0 || eq_ptr->b > 20.0 ||
				eq_ptr->c < 30.0 || eq_ptr->c > 750.0) {
				if (Send_Messages ()) {
					exe->Error ("Exponential Equation Parameters %.2lf, %.2lf, %.1lf are Out of Range", eq_ptr->a, eq_ptr->b, eq_ptr->c);
				}
			}
		} else if (eq_ptr->type == CONICAL) {
			if (eq_ptr->a <= 1.0 || eq_ptr->a > 20.0) {
				if (Send_Messages ()) {
					exe->Error ("Conical Equation Parameter %.2lf is Out of Range (1..20)", eq_ptr->a);
				}
				return (false);
			}
			eq_ptr->b = (2 * eq_ptr->a - 1) / (2 * eq_ptr->a - 2);
		} else if (eq_ptr->type == AKCELIK) {
			if (eq_ptr->a <= 0.05 || eq_ptr->a > 2.5) {
				if (Send_Messages ()) {
					exe->Error ("AKCELIK Equation Parameter *.2lf is Out of Range (0.05..2.5)", eq_ptr->a);
				}
				return (false);
			}
		}
	} else if (type == 1) {

		eq_ptr->type = BPR;
		eq_ptr->a = 0.15;
		eq_ptr->b = 4.0;
		eq_ptr->c = 0.75;
		eq_ptr->d = 0.0;

	} else {

		Equation *prev_ptr = (Equation *) Record (type-1);

		if (prev_ptr == NULL) return (false);

		*eq_ptr = *prev_ptr;
		return (true);
	}

	if (Send_Messages ()) {
		exe->Print (1, "Equation Parameters %d = %s, A=%0.2lf",
			type, eq_text [eq_ptr->type], eq_ptr->a);

		if (eq_ptr->type != CONICAL && eq_ptr->type != AKCELIK) {
			exe->Print (0, ", B=%0.2lf, C=%.2lf", eq_ptr->b, eq_ptr->c);
		}
		if (eq_ptr->type == BPR_PLUS) {
			exe->Print (0, ", D=%.2lf", eq_ptr->d);
		}
	}
	return (true);
}
Exemple #14
0
/*************************************************************************
 *
 *  Parse_Proc_Stmt() - See if "token" is the start of a procedural
 *  statement, and, if so, build the statement and return a pointer
 *  to it, otherwise, return NULL.
 *
 ************************************************************************/
STATEMENT *Parse_Proc_Stmt(int token)

{
  STATEMENT *stmt, *st;

  if((cur_token->flags & TKFLAG_PROC) == 0)
  	return NULL;

  stmt = New_Statement(token);

  switch(token)
	{
		case TK_BREAK:
			stmt->exec = Exec_Break;
      stmt->expr = Compile_Expr();
			break;

		case TK_DO:
			stmt->exec = Exec_Do;
			stmt->block = Parse_Block("do");
			Expect(TK_WHILE, "while", "do");
      if((stmt->expr = Compile_Expr()) == NULL)
				SCN_Message(SCN_MSG_ERROR,
          "do: Numeric expression expected after `while'. Found `%s'.",
				token_buffer);
			break;

    case TK_IF:
      stmt->exec = Exec_If;
      if((stmt->expr = Compile_Expr()) == NULL)
				SCN_Message(SCN_MSG_ERROR, "if: Numeric expression expected. Found `%s'.",
				token_buffer);
		  stmt->block = Parse_Block("if");
			st = stmt;
			while(1)
			{
				if((token = Get_Token()) == TK_ELSE)
				{
					st->next = New_Statement(TK_ELSE);
					st = st->next;
					st->exec = Exec_If;
					if(Get_Token() == TK_IF)
					{
			      if((st->expr = Compile_Expr()) == NULL)
           	{
							SCN_Message(SCN_MSG_ERROR, "else if: Numeric expression expected. Found `%s'.",
							token_buffer);
              break;
            }
						st->block = Parse_Block("else if");
					}
					else
					{
						Unget_Token();
						st->block = Parse_Block("else");
						break;   /* from loop */
					}
				}
				else if(token == TK_ELIF)
				{
					st->next = New_Statement(TK_ELSE);
					st = st->next;
					st->exec = Exec_If;
		      if((st->expr = Compile_Expr()) == NULL)
         	{
						SCN_Message(SCN_MSG_ERROR, "elif: Numeric expression expected. Found `%s'.",
						token_buffer);
            break;
          }
					st->block = Parse_Block("elif");
				}
				else
				{
					Unget_Token();
					break;   /* from loop */
				}
			}
    	break;

		case TK_NEXT:
			stmt->exec = Exec_Next;
			break;

		case TK_REPEAT:
			stmt->exec = Exec_Repeat;
      if((stmt->expr = Compile_Expr()) == NULL)
				SCN_Message(SCN_MSG_ERROR,
          "repeat: Numeric expression expected. Found `%s'.",
				token_buffer);
		  stmt->block = Parse_Block("repeat");
			break;

		case TK_RETURN:
			stmt->exec = Exec_Return;
      stmt->expr = Compile_Expr();
			break;

		case TK_WHILE:
			stmt->exec = Exec_While;
      if((stmt->expr = Compile_Expr()) == NULL)
				SCN_Message(SCN_MSG_ERROR,
          "while: Numeric expression expected. Found `%s'.",
				token_buffer);
			stmt->block = Parse_Block("while");
			break;

		case DECL_PROC:
			stmt->exec = Exec_Proc;
      stmt->data.proc = Copy_User_Proc((Proc *)cur_token->data);
			stmt->params = Compile_Proc_Params(stmt->data.proc->params);
			break;

    default:
      SCN_Message(SCN_MSG_ERROR, "Unknown statement type in Parse_Proc_Stmt()");
    	break;
  }

  if(scn_error_cnt)
	{
  	Delete_Statement(stmt);
    stmt = NULL;
  }

  return stmt;
}
Exemple #15
0
/*************************************************************************
 *
 * Parse_Local_Decl() - Process user defined types and declarations
 *   that are local to the body of a user-defined procedure.
 *   Assumes that a non-keyword identifier name has just been parsed
 *   and the global, "token_buffer", contains the name. If
 *   initialization expressions are processed, a STATEMENT list will
 *   be constructed and returned.
 *
 ************************************************************************/
STATEMENT *Parse_Local_Decl(Proc *proc, int type, const char *block_name)
{
	int token;
  STATEMENT *stmt = NULL, *s = NULL;
  EXPR *expr;
  static char name[MAX_TOKEN_BUF_SIZE];

  assert(proc != NULL);

  local_only = 1;
	if((token = Get_Token()) != TK_STRING)
		Err_Unknown(token, "identifier", block_name);
  local_only = 0;

  if(scn_error_cnt)
  	return NULL;

	strcpy(name, token_buffer);
	switch(type)
	{
		case TK_FLOAT:
		case TK_VECTOR:
		{
			LVALUE *lv;

			while(1)
			{
				/* Initialize l-value data structure... */
				lv = New_Lvalue(type);

				/* If there is an initializer expr? */
        if((expr = Compile_Lvalue_Expr(lv)) != NULL)
       	{
          if(s != NULL)
         	{
            s->next = New_Statement(TK_PROC_EXPR);
            s = s->next;
          }
          else
	          s = stmt = New_Statement(TK_PROC_EXPR);
				  s->exec = Exec_Expr;
          s->expr = expr;
				}

				/* Add new l-value to dictionary and proc... */
				Add_Symbol(name, (void *)lv, DECL_LVALUE);
        Proc_Add_Local(proc, lv);

				if(Get_Token() != OP_COMMA)
       	{
          Unget_Token();
					break;  /* Done, break from loop. */
        }

				/*
				 * Gotta comma. Get next name, and recycle...
				 */
        local_only = 1;
				if((token = Get_Token()) != TK_STRING)
					Err_Unknown(token, "identifier", block_name);
        local_only = 0;
				strcpy(name, token_buffer);
			} /* end of comma loop */
		}
		  break;

		default:
			SCN_Message(SCN_MSG_ERROR, "%s: Invalid declaration type.", block_name);
			break;
	} /* end of "type" switch */

  return stmt;
} /* end of Parse_Local_Decl() */
Exemple #16
0
void PlanSelect::Program_Control (void)
{
	int i, nsel, lvalue;
	char *str_ptr, buffer [FIELD_BUFFER];
	double dvalue;
	Box box;

	//---- open network files ----

	Demand_Service::Program_Control ();

	//---- open the plan file ----
	
	if (Get_Control_String (NODE_LIST_PATHS) != NULL) {
		type_flag = Get_Control_Flag (NODE_LIST_PATHS);
	}
	str_ptr = Get_Control_String (PLAN_FILE);

	if (str_ptr == NULL) goto control_error;

	str_ptr = Project_Filename (str_ptr, Extension ());

	Print_Filename (2, plan_file.File_Type (), str_ptr);

	plan_file.Filename (str_ptr);

	str_ptr = Get_Control_String (PLAN_FORMAT);

	if (str_ptr != NULL) {
		plan_file.File_Format (str_ptr);
		Print (1, "%s Format = %s", plan_file.File_Type (), str_ptr);
	}
	plan_file.Node_Based_Flag (type_flag);

	if (!plan_file.Open (0)) {
		File_Error ("Opening Plan File", plan_file.Filename ());
	}
	type_flag = plan_file.Node_Based_Flag ();

	//---- node list paths ----

	if (type_flag) {
		Print (1, "Plan File contains Node List Paths");
	} else {
		Print (1, "Plan File contains Link List Paths");
	}

	//---- check for a link delay file ----

	if (Demand_File_Flag (LINK_DELAY)) {
		Delay_File *file = (Delay_File *) Demand_Db_File (LINK_DELAY);

		if (!Network_File_Flag (LINK) || !Network_File_Flag (NODE)) {
			Error ("Link and Node files are Required for Link Delay Processing");
		}
		if (file->Dbase_Format () == VERSION3) {
			turn_flag = false;
			Network_File_False (LANE_CONNECTIVITY);
		} else if (!Network_File_Flag (LANE_CONNECTIVITY)) {
			Warning ("Lane Connectivity is required for Turning Delays");
			Show_Message (1);
			turn_flag = false;
		} else {
			turn_flag = true;
		}
		delay_flag = true;
	} else {
		Network_File_False (LANE_CONNECTIVITY);
	}

	//---- open the population file ----

	str_ptr = Get_Control_String (POPULATION_FILE);

	if (str_ptr != NULL) {
		pop_file.File_Type ("Population File");
		Print (1);

		pop_file.Open (str_ptr);
		pop_flag = true;
	}

	//---- get the household list ----

	str_ptr = Get_Control_String (NEW_HOUSEHOLD_LIST);

	if (str_ptr != NULL) {
		hhlist_file.File_Type ("New Household List");
		hhlist_file.File_Access (CREATE);

		str_ptr = Project_Filename (str_ptr, Extension ());
		hhlist_file.Filename (str_ptr);

		Print_Filename (2, hhlist_file.File_Type (), str_ptr);

		if (!hhlist_file.Open (0)) {
			File_Error ("Opening Household List File", hhlist_file.Filename ());
		}
		if (hhlist_file.Extend () == 0 && plan_file.Extend () != 0) {
			Warning ("Household List File is Not Partitioned");
		}
	} else {
		str_ptr = Get_Control_String (NEW_HOUSEHOLD_RECORD_FILE);

		if (str_ptr == NULL) {
			Error ("A New Household List or Household Record File is Required");
		}
		hhrec_flag = true;
		hhrec_file.File_Access (CREATE);

		str_ptr = Project_Filename (str_ptr, Extension ());
		hhrec_file.Filename (str_ptr);

		Print_Filename (2, hhrec_file.File_Type (), str_ptr);

		str_ptr = Get_Control_String (NEW_HOUSEHOLD_RECORD_FORMAT);

		if (str_ptr != NULL) {
			hhrec_file.Dbase_Format (str_ptr);
			Print (1, "%s Format = %s", hhrec_file.File_Type (), str_ptr);
		}
		if (!hhrec_file.Open (0)) {
			File_Error ("Opening Household Record file", hhrec_file.Filename ());
		}
		if (hhrec_file.Extend () == 0 && plan_file.Extend () != 0) {
			Warning ("Household Record File is Not Partitioned");
		}
	}

	//---- get the select travelers ----
	
	str_ptr = Get_Control_String (SELECT_TRAVELERS);

	if (str_ptr != NULL) {
		Print (2, "Select Traveler IDs = %s", str_ptr);

		if (!travelers.Add_Ranges (str_ptr)) {
			File_Error ("Traveler ID Range", str_ptr);
		}
	}
	
	//---- get the select nodes ----

	nsel = Highest_Control_Group (SELECT_NODES_x, 0);

	if (nsel > 0) {

		nodes.Max_Records (nsel);

		for (i=1; i <= nsel; i++) {
			str_ptr = Get_Control_String (SELECT_NODES_x, i);

			if (str_ptr == NULL) continue;

			Print (2, "Select Nodes for Group #%d = %s", i, str_ptr);

			Data_Range *ptr = new Data_Range ();

			if (!ptr->Add_Ranges (str_ptr)) {
				File_Error ("Path Node Numbers", str_ptr);
			}
			if (!nodes.Add (ptr)) {
				Error ("Adding Node Ranges to the List");
			}
		}
	}
	
	//---- get the select links ----

	nsel = Highest_Control_Group (SELECT_LINKS_x, 0);

	if (nsel > 0) {

		links.Max_Records (nsel);

		for (i=1; i <= nsel; i++) {
			str_ptr = Get_Control_String (SELECT_LINKS_x, i);

			if (str_ptr == NULL) continue;

			Print (2, "Select Links for Group #%d = %s", i, str_ptr);

			Data_Range *ptr = new Data_Range (1, -MAX_INTEGER, MAX_INTEGER, 0);

			if (!ptr->Add_Ranges (str_ptr)) {
				File_Error ("Path Link Numbers", str_ptr);
			}
			if (!links.Add (ptr)) {
				Error ("Adding Link Ranges to the List");
			}
		}
	}

	//---- get the select time periods ----
	
	str_ptr = Get_Control_String (SELECT_TIME_PERIODS);

	if (str_ptr != NULL) {
		Print (2, "Select Time Periods = %s", str_ptr);

		times.Format (Time_Step::HOURS);

		if (!times.Add_Ranges (str_ptr)) {
			File_Error ("Time Period Range", str_ptr);
		}
	}
	
	//---- get the select travel modes ----

	str_ptr = Get_Control_String (SELECT_TRAVEL_MODES);

	if (str_ptr != NULL) {

		Print (2, "Select Travel Modes = %s", str_ptr);

		memset (mode_flag, '\0', sizeof (mode_flag));
		nsel = 0;

		while (str_ptr != NULL) {
			char *old_ptr = str_ptr;

			str_ptr = Get_Integer (str_ptr, &i);

			if (i < 0 || i > DRIVER_MODE || (i == 0 && *old_ptr != '0')) {
				Error ("Selected Travel Mode %s is Out of Range (0..%d)", old_ptr, DRIVER_MODE);
			}
			mode_flag [i] = true;
			nsel++;
		}
		if (nsel == 0) {
			Error ("No Modes were Selected for Processing");
		}
	} else {
		for (i=0; i <= DRIVER_MODE; i++) {
			mode_flag [i] = true;
		}
	}

	//---- get the select facility types ----

	str_ptr = Get_Control_String (SELECT_FACILITY_TYPES);

	if (str_ptr != NULL) {

		Print (2, "Select Facility Types = %s", str_ptr);

		factype_flag = true;
		memset (facility_flag, '\0', sizeof (facility_flag));
		nsel = 0;

		while (str_ptr != NULL) {
			str_ptr = Get_Token (str_ptr, buffer, sizeof (buffer));
			if (buffer [0] == '\0') break;

			i = Facility_Code (buffer);
			facility_flag [i] = true;
			nsel++;
		}
		if (nsel == 0) {
			Error ("No Facility Types were Selected for Processing");
		}
	}

	//---- get the select locations ----
	
	str_ptr = Get_Control_String (SELECT_LOCATIONS);

	if (str_ptr != NULL) {
		Print (2, "Select Activity Locations = %s", str_ptr);

		if (!locations.Add_Ranges (str_ptr)) {
			File_Error ("Activity Location Range", str_ptr);
		}
	}

	//---- get the select parking lots ----
	
	str_ptr = Get_Control_String (SELECT_PARKING_LOTS);

	if (str_ptr != NULL) {
		Print (2, "Select Parking Lots = %s", str_ptr);

		if (!parking_lots.Add_Ranges (str_ptr)) {
			File_Error ("Parking Lot Range", str_ptr);
		}
	}

	//---- get the select transit stops ----
	
	str_ptr = Get_Control_String (SELECT_TRANSIT_STOPS);

	if (str_ptr != NULL) {
		Print (2, "Select Transit Stops = %s", str_ptr);

		if (!transit_stops.Add_Ranges (str_ptr)) {
			File_Error ("Transit Stop Range", str_ptr);
		}
	}

	//---- get the select transit routes ----
	
	str_ptr = Get_Control_String (SELECT_TRANSIT_ROUTES);

	if (str_ptr != NULL) {
		Print (2, "Select Transit Routes = %s", str_ptr);

		if (!transit_routes.Add_Ranges (str_ptr)) {
			File_Error ("Transit Route Range", str_ptr);
		}
	}

	//---- get the select vc ratio ----

	str_ptr = Get_Control_String (SELECT_VC_RATIOS);

	if (str_ptr != NULL) {
		if (!delay_flag) {
			Error ("Select V/C Ratios requires a Link Delay file");
		}
		vc_flag = true;
		Get_Double (str_ptr, &vc_ratio);

		if (vc_ratio < 1.0) {
			Error ("Select V/C Ratios %.2lf is Out of Range (>= 1.0)", vc_ratio);
		}
		Print (2, "Select V/C Ratios >= %.2lf", vc_ratio);
	}

	//---- get the select time ratio ----

	str_ptr = Get_Control_String (SELECT_TIME_RATIOS);

	if (str_ptr != NULL) {
		if (!delay_flag) {
			Error ("Select Travel Time Ratios requires a Link Delay file");
		}
		ratio_flag = true;
		Get_Double (str_ptr, &time_ratio);

		if (time_ratio < 1.0) {
			Error ("Select Time Ratios %.2lf is Out of Range (>= 1.0)", time_ratio);
		}
		Print (2, "Select Time Ratios >= %.2lf", time_ratio);
	}

	//---- get the select coordinates ----

	nsel = Highest_Control_Group (SELECT_COORDINATES_x, 0);

	for (i=0; i <= nsel; i++) {
		if (i == 0) {
			str_ptr = Get_Control_String (SELECT_COORDINATES);
		} else {
			str_ptr = Get_Control_String (SELECT_COORDINATES_x, i);
		}
		if (str_ptr == NULL) continue;

		if (!Network_File_Flag (NODE)) {
			Error ("Select Coordinates requires a Node file");
		}
		coord_flag = true;

		if (i == 0) {
			Print (2, "Select Coordinates = %s", str_ptr);
		} else {
			if (coord_box.Num_Records () == 0) Print (1);

			Print (1, "Select Coordinates #%d = %s", i, str_ptr);
		}
		str_ptr = Get_Double (str_ptr, &dvalue);
		box.x1 = Round (dvalue);

		if (str_ptr == NULL) goto coord_error;

		str_ptr = Get_Double (str_ptr, &dvalue);
		box.y1 = Round (dvalue);

		if (str_ptr == NULL) goto coord_error;

		str_ptr = Get_Double (str_ptr, &dvalue);
		box.x2 = Round (dvalue);

		if (box.x2 < box.x1) {
			lvalue = box.x2;
			box.x2 = box.x1;
			box.x1 = lvalue;
		}
		if (str_ptr == NULL) goto coord_error;

		str_ptr = Get_Double (str_ptr, &dvalue);
		box.y2 = Round (dvalue);

		if (box.y2 < box.y1) {
			lvalue = box.y2;
			box.y2 = box.y1;
			box.y1 = lvalue;
		}
		if (!coord_box.Add (&box)) goto mem_error;
	}

	//---- get the select od coordinates ----

	nsel = Highest_Control_Group (SELECT_OD_COORDINATES_x, 0);

	for (i=0; i <= nsel; i++) {
		if (i == 0) {
			str_ptr = Get_Control_String (SELECT_OD_COORDINATES);
		} else {
			str_ptr = Get_Control_String (SELECT_OD_COORDINATES_x, i);
		}
		if (str_ptr == NULL) continue;

		if (!Network_File_Flag (NODE)) {
			Error ("Select OD Coordinates requires a Node file");
		}
		in_flag = true;

		if (i == 0) {
			Print (2, "Select OD Coordinates = %s", str_ptr);
		} else {
			if (od_box.Num_Records () == 0) Print (1);

			Print (1, "Select OD Coordinates #%d = %s", i, str_ptr);
		}
		str_ptr = Get_Double (str_ptr, &dvalue);
		box.x1 = Round (dvalue);

		if (str_ptr == NULL) goto coord_error;

		str_ptr = Get_Double (str_ptr, &dvalue);
		box.y1 = Round (dvalue);

		if (str_ptr == NULL) goto coord_error;

		str_ptr = Get_Double (str_ptr, &dvalue);
		box.x2 = Round (dvalue);

		if (box.x2 < box.x1) {
			lvalue = box.x2;
			box.x2 = box.x1;
			box.x1 = lvalue;
		}
		if (str_ptr == NULL) goto coord_error;

		str_ptr = Get_Double (str_ptr, &dvalue);
		box.y2 = Round (dvalue);

		if (box.y2 < box.y1) {
			lvalue = box.y2;
			box.y2 = box.y1;
			box.y1 = lvalue;
		}
		if (!od_box.Add (&box)) goto mem_error;
	}

	//---- get the exclude od coordinates ----

	nsel = Highest_Control_Group (EXCLUDE_OD_COORDINATES_x, 0);

	for (i=0; i <= nsel; i++) {
		if (i == 0) {
			str_ptr = Get_Control_String (EXCLUDE_OD_COORDINATES);
		} else {
			str_ptr = Get_Control_String (EXCLUDE_OD_COORDINATES_x, i);
		}
		if (str_ptr == NULL) continue;

		if (!Network_File_Flag (NODE)) {
			Error ("Excludet OD Coordinates requires a Node file");
		}
		out_flag =  true;

		if (i == 0) {
			Print (2, "Exclude OD Coordinates = %s", str_ptr);
		} else {
			if (exclude_box.Num_Records () == 0) Print (1);

			Print (1, "Excludet OD Coordinates #%d = %s", i, str_ptr);
		}
		str_ptr = Get_Double (str_ptr, &dvalue);
		box.x1 = Round (dvalue);

		if (str_ptr == NULL) goto od_coord_error;

		str_ptr = Get_Double (str_ptr, &dvalue);
		box.y1 = Round (dvalue);

		if (str_ptr == NULL) goto od_coord_error;

		str_ptr = Get_Double (str_ptr, &dvalue);
		box.x2 = Round (dvalue);

		if (box.x2 < box.x1) {
			lvalue = box.x2;
			box.x2 = box.x1;
			box.x1 = lvalue;
		}
		if (str_ptr == NULL) goto od_coord_error;

		str_ptr = Get_Double (str_ptr, &dvalue);
		box.y2 = Round (dvalue);

		if (box.y2 < box.y1) {
			lvalue = box.y2;
			box.y2 = box.y1;
			box.y1 = lvalue;
		}
		if (!exclude_box.Add (&box)) goto mem_error;
	}

	//---- get the select subarea polygon ----

	str_ptr = Get_Control_String (SELECT_SUBAREA_POLYGON);

	if (str_ptr != NULL) {
		if (!Network_File_Flag (LINK) || !Network_File_Flag (NODE)) {
			Error ("Link and Node files are Required for Subarea Polygon Selection");
		}
		Print (1);
		select_subarea.File_Type ("Select Subarea Polygon");

		select_subarea.Open (Project_Filename (str_ptr));
		
		if (!select_subarea.Read_Record ()) {
			Error ("Reading %s", select_subarea.File_Type ());
		}
		subarea_flag = true;
	}

	//---- get the select vehicle types ----
	
	str_ptr = Get_Control_String (SELECT_VEHICLE_TYPES);

	if (str_ptr != NULL) {
		Print (2, "Select Vehicle Types = %s", str_ptr);

		if (!vehicle_types.Add_Ranges (str_ptr)) {
			File_Error ("Vehicle Type Range", str_ptr);
		}
		vehicle_flag = true;
		if (!Demand_File_Flag (VEHICLE)) {
			Error ("A Vehicle File is Required for Vehicle Type Selection");
		}
	} else {
		Demand_File_False (VEHICLE);
	}

	//---- get the percent time difference ----

	str_ptr = Get_Control_String (PERCENT_TIME_DIFFERENCE);

	if (str_ptr != NULL) {
		if (!delay_flag) {
			Error ("Percent Time Difference requires a Link Delay file");
		}
		diff_flag = true;
        Get_Double (str_ptr, &percent_diff);

		if (percent_diff < 0.1 || percent_diff > 100.0) {
			Error ("Percent Time Difference %.2lf is Out of Range (0.1-100.0)", percent_diff);
		}
		Print (2, "Percent Time Difference = %.1lf%%", percent_diff);

		percent_diff /= 100.0;

		//---- get the minimum time difference ----

		str_ptr = Get_Control_String (MINIMUM_TIME_DIFFERENCE);

		if (str_ptr != NULL) {
			Get_Integer (str_ptr, &min_time);

			if (min_time < 0 || min_time > 120) {
				Error ("Minimum Time Difference %d is Out of Range (0-120)", min_time);
			}
		}
		Print (1, "Minimum Time Difference = %d minute%s", 
			min_time, ((min_time != 1) ? "s" : " "));

		//---- get the maximum time difference ----

		str_ptr = Get_Control_String (MAXIMUM_TIME_DIFFERENCE);

		if (str_ptr != NULL) {
			Get_Integer (str_ptr, &max_time);

			if (max_time < min_time || max_time > 1440) {
				Error ("Maximum Time Difference %d is Out of Range (%d-1440)", max_time, min_time);
			}
		}
		Print (1, "Maximum Time Difference = %d minutes", max_time);

		min_time *= 60;
		max_time *= 60;
	}

	//---- get the selection percentage ----

	str_ptr = Get_Control_String (SELECTION_PERCENTAGE);

	if (str_ptr != NULL) {
		Get_Double (str_ptr, &percent);

		if (percent < 0.1 || percent > 100.0) {
			Error ("Selection Percentage %.2lf is Out of Range (0.1-100.0)", percent);
		}
		select_flag = (percent != 100.0);
	}
	Print (2, "Selection Percentage = %.1lf%%", percent);

	percent /= 100.0;

	//---- get the max percent selected ----

	str_ptr = Get_Control_String (MAXIMUM_PERCENT_SELECTED);

	if (str_ptr != NULL) {
		Get_Double (str_ptr, &max_percent);

		if (max_percent < 1.0 || max_percent > 100.0) {
			Error ("Maximum Percent Selected %.1lf is Out of Range (1.0-100.0)", max_percent);
		}
	}
	Print (1, "Maximum Percent Selected = %.1lf%%", max_percent);

	max_percent /= 100.0;

	//---- random number seed ----

	str_ptr = Get_Control_String (RANDOM_NUMBER_SEED);

	if (str_ptr != NULL) {
		random.Seed (atoi (str_ptr));
	}
	if (str_ptr != NULL || percent != 1.0 || max_percent != 1.0) {
		Print (1, "Random Number Seed = %d", random.Seed ());
	}

	//---- reset the network flags ----

	if (!vc_flag && !diff_flag && !ratio_flag) {
		delay_flag = parking_flag = turn_flag = false;
		Demand_File_False (LINK_DELAY);
		Network_File_False (LANE_USE);
		Network_File_False (PARKING);
		Network_File_False (LANE_CONNECTIVITY);

		if (!coord_flag && !out_flag && !in_flag && !subarea_flag && !factype_flag && 
			nodes.Num_Records () == 0 && links.Num_Records () == 0) {
			Network_File_False (LINK);
			Network_File_False (NODE);
			Network_File_False (TRANSIT_STOP);
			Network_File_False (TRANSIT_DRIVER);
		} else if (!factype_flag && type_flag && links.Num_Records () == 0) {
			Network_File_False (LINK);
		}
	} else {
		parking_flag = Network_File_Flag (PARKING);

		if (!diff_flag) {
			turn_flag = false;
			Network_File_False (LANE_CONNECTIVITY);
		}
	}
	transit_flag = (Network_File_Flag (TRANSIT_STOP) && Network_File_Flag (TRANSIT_DRIVER));

	return;

	//---- error message ----

control_error:
	Error ("Missing Control Key = %s", Current_Key ());

coord_error:
	Error ("Select Coordinates are Incomplete");

od_coord_error:
	Error ("Exclude OD Coordinates are Incomplete");

mem_error:
	Error ("Insufficient Memory for Coordinate Groups");
} 
Exemple #17
0
void ZoneData::Program_Control (void)
{
	int i, size, num, decimal, existing;
	char *str_ptr, *format_ptr, name [FIELD_BUFFER], buffer [FIELD_BUFFER];
	Db_Code::Field_Type type;

	Db_Header *file;

	//---- open network files ----

	Network_Service::Program_Control ();

	input_file = (Zone_File *) Network_Db_File (ZONE);
	input_file->File_ID ("In");

	output_file = (Zone_File *) Network_Db_File (NEW_ZONE);
	output_file->File_ID ("Out");

	//---- copy existing fields ----

	str_ptr = Get_Control_String (COPY_EXISTING_FIELDS);

	if (str_ptr != NULL) {
		Print (2, "Copy Existing Fields = %s", str_ptr);

		copy_flag = Get_Control_Flag (COPY_EXISTING_FIELDS);

		if (copy_flag) {
			output_file->Clear_Fields ();
			output_file->Replicate_Fields (input_file, false);
		}
	}

	//---- get the new zone fields ----

	num = Highest_Control_Group (NEW_ZONE_FIELD_x, 0);

	if (num == 0) {
		if (Get_Control_String (NEW_ZONE_FIELD) != NULL) {
			num = 1;
		}
	} else {
		num++;
	}

	if (num == 0) {
		if (!copy_flag) {
			Warning ("No New Zone Fields");
		}
	} else {
		Print (1);

		for (i=0; i < num; i++) {
			if (i == 0) {
				str_ptr = Get_Control_String (NEW_ZONE_FIELD);
			} else {
				str_ptr = Get_Control_String (NEW_ZONE_FIELD_x, i);
			}
			if (str_ptr == NULL) continue;

			if (i == 0) {
				Print (1, "New Zone Field = %s", str_ptr);
			} else {
				Print (1, "New Zone Field #%d = %s", i, str_ptr);
			}
			str_ptr = Get_Token (str_ptr, name, sizeof (name));
			if (name [0] == '\0') goto data_error;

			existing = output_file->Field_Number (name);
			if (existing != 0) goto field_error;

			str_ptr = Get_Token (str_ptr, buffer, sizeof (buffer));
			if (buffer [0] == '\0' || buffer [0] == 'I') {
				type = INTEGER;
			} else if (buffer [0] == 'R' || buffer [0] == 'D') {
				type = DOUBLE;
			} else if (buffer [0] == 'S' || buffer [0] == 'C') {
				type = STRING;
			} else {
				goto data_error;
			}
			str_ptr = Get_Token (str_ptr, buffer);
			if (buffer [0] == '\0') {
				size = 10;
				if (type == DOUBLE) {
					decimal = 2;
				} else {
					decimal = 0;
				}
			} else {
				size = atoi (buffer);

				if (type == DOUBLE) {
					str_ptr = strchr (buffer, '.');
					if (str_ptr != NULL) {
						decimal = atoi (str_ptr+1);
					} else {
						decimal = 2;
					}
				} else {
					decimal = 0;
				}
			}
			output_file->Add_Field (name, type, size, decimal);
		}
	}
	if (copy_flag && output_file->Notes_Flag ()) {
		if (output_file->Field_Number ("NOTES") == 0) {
			output_file->Add_Field ("NOTES", STRING, FIELD_BUFFER);
		}
	}
	output_file->Write_Header ();
	
	//---- check for data files ----

	num_data_files = Highest_Control_Group (DATA_FILE_x, 0);

	if (num_data_files == 0) {
		if (Get_Control_String (DATA_FILE) != NULL) {
			num_data_files = 1;
		}
	} else {
		num_data_files++;
	}
	if (num_data_files > 0) {
		data_flag = true;
	}

	//---- check for polygon files ----

	num_polygons = Highest_Control_Group (BOUNDARY_POLYGON_x, 0);

	if (num_polygons == 0) {
		if (Get_Control_String (BOUNDARY_POLYGON) != NULL) {
			num_polygons = 1;
		}
	} else {
		num_polygons++;
	}
	if (num_polygons > 0) {
		polygon_flag = true;
	}

	//---- read conversion script ----

	str_ptr = Get_Control_String (CONVERSION_SCRIPT);

	if (str_ptr == NULL) {
		if (data_flag || polygon_flag) {
			Error ("A Convertion Script is needed for Data Processing");
		}
	} else {
		script_flag = true;
		Print (1);
		program_file.File_Type ("Conversion Script");
		program_file.Open (Project_Filename (str_ptr));
		Print (1);
	}

	//---- read data files ----

	if (data_flag) {

		//---- allocate data files ----

		data_files = new Db_Header * [num_data_files];
		data_field = new int [num_data_files];
		zone_field = new int [num_data_files];

		if (data_files == NULL || data_field == NULL || zone_field == NULL) {
			Error ("Insufficient Memory for %d Data Files", num_data_files);
		}
		memset (data_files, '\0', num_data_files * sizeof (Db_Header *));
		memset (data_field, '\0', num_data_files * sizeof (int));
		memset (zone_field, '\0', num_data_files * sizeof (int));

		//---- open each file ----

		for (i=0; i < num_data_files; i++) {
			if (i == 0) {
				str_ptr = Get_Control_String (DATA_FILE);
			} else {
				str_ptr = Get_Control_String (DATA_FILE_x, i);
			}
			if (str_ptr == NULL) continue;

			//---- create a header file and file labels ----

			Print (1);
			data_files [i] = file = new Db_Header ();

			if (i == 0) {
				file->File_Type ("Data File");
				file->File_ID ("Data");
				format_ptr = Get_Control_String (DATA_FORMAT);
			} else {
				str_fmt (buffer, sizeof (buffer), "Data File #%d", i);
				file->File_Type (buffer);

				str_fmt (buffer, sizeof (buffer), "Data%d", i);
				file->File_ID (buffer);

				format_ptr = Get_Control_String (DATA_FORMAT_x, i);
			}

			//---- open the file ----

			if (format_ptr != NULL) {
				file->Dbase_Format (format_ptr);
			}
			file->Open (Project_Filename (str_ptr));

			//---- find the data join field ----

			if (i == 0) {
				str_ptr = Get_Control_String (DATA_JOIN_FIELD);
			} else {
				str_ptr = Get_Control_String (DATA_JOIN_FIELD_x, i);
			}
			if (str_ptr == NULL) goto control_error;

			data_field [i] = file->Field_Number (str_ptr);

			if (data_field [i] == 0) {
				Error ("Data Join Field %s was Not Found", str_ptr);
			}
			if (i == 0) {
				Print (1, "Data Join Field = %s, Number = %d", str_ptr, data_field [i]);
			} else {
				Print (1, "Data Join Field #%d = %s, Number = %d", i, str_ptr, data_field [i]);
			}

			//---- find the zone join field ----

			if (i == 0) {
				str_ptr = Get_Control_String (ZONE_JOIN_FIELD);
			} else {
				str_ptr = Get_Control_String (ZONE_JOIN_FIELD_x, i);
			}
			if (str_ptr == NULL) goto control_error;

			zone_field [i] = input_file->Field_Number (str_ptr);

			if (zone_field [i] == 0) {
				Error ("Zone Join Field %s was Not Found", str_ptr);
			}
			if (i == 0) {
				Print (1, "Zone Join Field = %s, Number = %d", str_ptr, zone_field [i]);
			} else {
				Print (1, "Zone Join Field #%d = %s, Number = %d", i, str_ptr, zone_field [i]);
			}
		}
	}

	//---- read the boundary polygons ----

	if (polygon_flag) {
		Arcview_File *poly_file;

		projection.Read_Control ();

		//---- allocate data files ----

		polygon_files = new Arcview_File * [num_polygons];
		polygons = new Index_Array * [num_polygons];
		polygon_db = new Db_Index_Array * [num_polygons];

		if (polygon_files == NULL || polygons == NULL || polygon_db == NULL) {
			Error ("Insufficient Memory for %d Polygon Files", num_polygons);
		}
		memset (polygon_files, '\0', num_polygons * sizeof (Arcview_File *));
		memset (polygons, '\0', num_polygons * sizeof (Index_Array *));
		memset (polygon_db, '\0', num_polygons * sizeof (Db_Index_Array *));

		//---- open each file ----

		for (i=0; i < num_polygons; i++) {
			if (i == 0) {
				str_ptr = Get_Control_String (BOUNDARY_POLYGON);
			} else {
				str_ptr = Get_Control_String (BOUNDARY_POLYGON_x, i);
			}
			if (str_ptr == NULL) continue;

			//---- open the file ----

			polygon_files [i] = poly_file = new Arcview_File ();
			polygons [i] = new Index_Array (sizeof (Boundary));

			poly_file->Set_Projection (projection.Input_Projection (), projection.Output_Projection ());

			Print (1);
			if (i == 0) {
				poly_file->File_Type ("Boundary Polygon File");
				poly_file->File_ID ("Polygon");
			} else {
				str_fmt (buffer, sizeof (buffer), "Boundary Polygon File #%d", i);
				poly_file->File_Type (buffer);

				str_fmt (buffer, sizeof (buffer), "Polygon%d", i);
				poly_file->File_ID (buffer);
			}
			poly_file->Open (Project_Filename (str_ptr));
		}
	}
	Show_Message (1);
	return;

control_error:
	Error ("Missing Control Key = %s", Current_Key ());

data_error:
	Error ("New Zone Field %d is Improperly Specified", i);

field_error:
	Error ("New Zone Field %s already exists as Field %d", name, existing);
}
Exemple #18
0
void TransimsNet::Program_Control (void)
{
	int i, num, lvalue;
	double dvalue;
	char *str_ptr, buffer [FIELD_BUFFER];

	Area_Type *type_ptr;

	//---- open network files ----

	Network_Service::Program_Control ();

	//---- set the file flags ----

	shape_flag = Network_File_Flag (NEW_SHAPE);
	zone_flag = Network_File_Flag (ZONE);
	zout_flag = Network_File_Flag (NEW_ZONE);

	name_flag = (((Link_File *) Network_Db_Base (LINK))->Name_Flag () && 
				((Link_File *) Network_Db_Base (NEW_LINK))->Name_Flag ());

	turn_flag = Network_File_Flag (TURN_PROHIBITION);

	//---- set the zone fields ----

	if (zout_flag) {
		if (!zone_flag) {
			Print (2, "Zone Centroids Copied from Node File");
		} else {
			Zone_File *file = (Zone_File *) Network_Db_File (ZONE);
			Zone_File *new_file = (Zone_File *) Network_Db_File (NEW_ZONE);

			new_file->Clear_Fields ();
			new_file->Replicate_Fields (file);
			new_file->Write_Header ();
		}
	}

	//---- keep node list ----
	
	str_ptr = Get_Control_String (KEEP_NODE_LIST);

	if (str_ptr != NULL) {
		Print (1);
		keep_nodes.File_Type ("Keep Node List File");

		keep_nodes.Open (Network_Filename (str_ptr));
	}

	//---- link node equivalance ----
	
	str_ptr = Get_Control_String (LINK_NODE_EQUIVALENCE);

	if (str_ptr != NULL) {
		Print (1);
		node_string.File_Type ("Link Node Equivalence File");

		node_string.Create (New_Filename (str_ptr));
	}

	//---- get the pocket lane lengths ----

	Print (1);

	num = Highest_Control_Group (POCKET_LENGTHS_FOR_FACILITY_x, 0);

	if (num >= EXTERNAL) num = EXTERNAL - 1;

	for (i=1; i <= num; i++) {
		str_ptr = Get_Control_String (POCKET_LENGTHS_FOR_FACILITY_x, i);
	
		if (str_ptr != NULL) {
			Print (1, "Pocket Lengths for Facility Type %d = %s meters", i, str_ptr);

			while (str_ptr != NULL) {
				str_ptr = Get_Double (str_ptr, &dvalue);

				if (dvalue < 0.0 || dvalue > 2000.0) {
					Error ("Pocket Length %.1lf for Facility %d is Out of Range (0..2000)", dvalue, i);
				}
				if (!pocket_len [i].Add (Round (dvalue))) {
					Error ("Adding Pocket Lane Length");
				}
			}
		}
	}

	//---- get the pocket to facility ----

	str_ptr = Get_Control_String (POCKET_TO_FACILITY_BY_AREA_TYPE);

	if (str_ptr != NULL) {
		pocket_to_flag = true;

		Print (1, "Pocket To Facility Types by Area Type = %s", str_ptr);

		while (str_ptr != NULL) {
			str_ptr = Get_Integer (str_ptr, &lvalue);

			if (lvalue < 0 || lvalue > EXTERNAL) {
				Error ("Pocket To Facility %d is Out of Range (0..%d)", lvalue, EXTERNAL);
			}
			if (!pocket_to.Add (lvalue)) {
				Error ("Adding Pocket To Facility");
			}
		}
	}

	//---- get the signal warrants ----

	Print (1);

	num = Highest_Control_Group (SIGNAL_WARRANT_FOR_AREA_TYPE_x, 0);

	for (i=1; i <= num; i++) {
		str_ptr = Get_Control_String (SIGNAL_WARRANT_FOR_AREA_TYPE_x, i);

		if (str_ptr != NULL) {
			Area_Type type_rec (i);

			Print (1, "Signal Warrant for Area Type %d = %s", i, str_ptr);

            str_ptr = Get_Token (str_ptr, buffer, sizeof (buffer));

			type_rec.Primary (Facility_Code (buffer));

			str_ptr = Get_Token (str_ptr, buffer, sizeof (buffer));

			type_rec.Secondary (Facility_Code (buffer));

			str_ptr = Get_Token (str_ptr, buffer, sizeof (buffer));

			if (*buffer == '\0') {
				str_cpy (buffer, sizeof (buffer), "ACTUATED");
			}

			type_rec.Signal_Type (Signal_Code (buffer));

			str_ptr = Get_Token (str_ptr, buffer, sizeof (buffer));

			if (*buffer == '\0') {
				str_cpy (buffer, sizeof (buffer), "SINGLE_RING");
			}

			type_rec.Ring_Type (Ring_Code (buffer));

			if (!area_type.Add (&type_rec)) goto type_error;
		}
	}

	//---- get the sign warrants ----

	Print (1);

	num = Highest_Control_Group (STOP_WARRANT_FOR_AREA_TYPE_x, 0);

	for (i=1; i <= num; i++) {
		str_ptr = Get_Control_String (STOP_WARRANT_FOR_AREA_TYPE_x, i);

		if (str_ptr != NULL) {
			type_ptr = area_type.Get (i);

			lvalue = Facility_Code (str_ptr);

			if (type_ptr == NULL) {
				Area_Type type_rec (i);
				type_rec.All_Stop (lvalue);

				if (!area_type.Add (&type_rec)) goto type_error;
			} else {
				type_ptr->All_Stop (lvalue);
			}
			Print (1, "Stop Warrant for Area Type %d = %s", i, str_ptr);
		}
	}

	//---- activity location side offset ----

	str_ptr = Get_Control_String (ACTIVITY_LOCATION_SIDE_OFFSET);

	if (str_ptr != NULL) {
		Get_Double (str_ptr, &location_side);

		if (location_side < 0.0 || location_side > 100.0) {
			Error ("Activity Location Side Offset %.2lf is Out of Range (0..100)", location_side);
		}
	}
	Print (2, "Activity Location Side Offset = %.2lf meters", location_side);

	//---- get the facility type access flags ----

	str_ptr = Get_Control_String (FACILITY_TYPE_ACCESS_FLAGS);

	if (str_ptr != NULL) {
		for (i=1; str_ptr != NULL; i++) {
			str_ptr = Get_Token (str_ptr, buffer, sizeof (buffer));

			if (*buffer == '\0') break;

			access_flag [i] = (*buffer == '1' || *buffer == 't' || *buffer == 'T' || 
				*buffer == 'y' || *buffer == 'Y');
		}
	}
	Print (2, "Facility Type Access Flags = ");

	for (i=1; i <= EXTERNAL; i++) {
		if (i > 1) {
			Print (0, ", %d", access_flag [i]);
		} else {
			Print (0, "%d", access_flag [i]);
		}
	}

	//---- get the number of access points ----

	str_ptr = Get_Control_String (MAXIMUM_ACCESS_POINTS);

	if (str_ptr == NULL) goto control_error;

	Get_Integer (str_ptr, &max_splits);

	if (max_splits < 1 || max_splits > 20) {
		Error ("Maximum Number of Access Points %d is Out of Range", max_splits);
	}
	Print (2, "Maximum Number of Access Points Per Link = %d", max_splits);

	//---- get the min split length ----

	str_ptr = Get_Control_String (MINIMUM_SPLIT_LENGTHS);

	if (str_ptr == NULL) goto control_error;

	Print (2, "Minimum Split Lengths = %s meters", str_ptr);

	for (i=1; str_ptr != NULL; i++) {
		str_ptr = Get_Integer (str_ptr, &lvalue);

		if (lvalue == 0) continue;

		if (lvalue < 40 || lvalue > 4000) {
			Error ("Minimum Split Length %d is Out of Range (40-4000)", lvalue);
		}
		lvalue = Round (lvalue);

		type_ptr = area_type.Get (i);

		if (type_ptr == NULL) {
			Area_Type type_rec (i);
			type_rec.Split_Len (lvalue);

			if (!area_type.Add (&type_rec)) goto type_error;
		} else {
			type_ptr->Split_Len (lvalue);
		}
	}

	//---- get the cell size ----

	str_ptr = Get_Control_String (CELL_SIZE);

	if (str_ptr != NULL) {
		Get_Double (str_ptr, &cell_size);

		if (cell_size < 4.0 || cell_size > 9.0) {
			Error ("Cell Size %.2lf is Out of Range (4..9)", cell_size);
		}
	}
	Print (2, "Cell Size = %.2lf meters", cell_size);

	//---- get the minimum link length ----

	str_ptr = Get_Control_String (MINIMUM_LINK_LENGTH);

	if (str_ptr != NULL) {
		Get_Double (str_ptr, &dvalue);

		if (dvalue < cell_size || dvalue > 100.0) {
			Error ("Minimum Link Length %.1lf is Out of Range (%.1lf..100.0)", dvalue, cell_size);
		}
	} else {
		dvalue = cell_size * 5.0;
	}
	min_length = Round (dvalue);
	Print (2, "Minimum Link Length = %.1lf meters", UnRound (min_length));

	//---- get the maximum length factor ----

	str_ptr = Get_Control_String (MAXIMUM_LENGTH_TO_XY_RATIO);

	if (str_ptr != NULL) {
		Get_Double (str_ptr, &max_length_factor);

		if (max_length_factor < 1.0 || max_length_factor > 2.0) {
			Error ("Maximum Length to XY Ratio %.1lf is Out of Range (1.0..2.0)", max_length_factor);
		}
	}
	Print (2, "Maximum Length to XY Ratio = %.2lf", max_length_factor);

	//---- get the maximum connection angle ----

	str_ptr = Get_Control_String (MAXIMUM_CONNECTION_ANGLE);

	if (str_ptr != NULL) {
		Get_Integer (str_ptr, &lvalue);

		if (lvalue < 90 || lvalue > 180) {
			Error ("Maximum Connection Angle %d is Out of Range (90..180)", lvalue);
		}
		max_angle = compass.Num_Points () * lvalue / 360;
	}
	Print (2, "Maximum Connection Angle = %d degrees", max_angle * 360 / compass.Num_Points ());

	//---- uturn flag ----

	uturn_flag = Get_Control_Flag (ADD_UTURN_TO_DEADEND_LINKS);

	if (uturn_flag) {
		Print (1, "U-Turns will be added to Dead-End Links");
	} else {
		Print (1, "U-Turns will not be added to Dead-End Links");
	}

	//---- get the setback distance ----

	str_ptr = Get_Control_String (INTERSECTION_SETBACK_DISTANCE);

	if (str_ptr != NULL) {
		Get_Double (str_ptr, &dvalue);

		if (dvalue < 0.0 || dvalue > 20.0) {
			Error ("Intersection Setback Distance %.1lf is Out of Range (0.0..20.0)", dvalue);
		}
	} else {
		dvalue = 0.0;
	}
	setback = Round (dvalue);
	Print (2, "Intersection Setback Distance = %.1lf meters", UnRound (setback));

	//---- get the external zone number ----

	str_ptr = Get_Control_String (FIRST_EXTERNAL_ZONE_NUMBER);

	if (str_ptr != NULL) {
		Get_Integer (str_ptr, &ext_zone);

		if (ext_zone < 0 || ext_zone > 10000) {
			Error ("External Zone Number %d is Out of Range (0..10000)", ext_zone);
		}
	} else {
		ext_zone = 0;
	}
	Print (2, "First External Zone Number = %d", ext_zone);

	//---- get the zone connector flag ----

	str_ptr = Get_Control_String (KEEP_ZONE_CONNECTORS_AS_LOCALS);

	if (str_ptr != NULL) {
		Print (1, "Keep Zone Connectors as Locals = %s", str_ptr);

		connect_flag = Get_Control_Flag (KEEP_ZONE_CONNECTORS_AS_LOCALS);
	}

	//---- get the replicate MPO network ----

	str_ptr = Get_Control_String (REPLICATE_MPO_NETWORK);

	if (str_ptr != NULL) {
		Print (1, "Replication MPO Network = %s", str_ptr);

		replicate_flag = Get_Control_Flag (REPLICATE_MPO_NETWORK);
	}

	//---- collapse nodes flag ----

	if (Get_Control_String (COLLAPSE_NODES_FLAG) != NULL) {
		collapse_flag = Get_Control_Flag (COLLAPSE_NODES_FLAG);
	}
	if (collapse_flag) {
		Print (2, "Extra Nodes will be Removed from the Network");
	} else {
		Print (2, "All Nodes in the Network will be Kept");
	}

	//---- update node range ----

	str_ptr = Get_Control_String (UPDATE_NODE_RANGE);

	if (str_ptr != NULL) {
		update_flag = true;
		Print (2, "Update Node Range = %s", str_ptr);

		if (!update_nodes.Add_Ranges (str_ptr)) {
			Error ("Adding Update Nodes");
		}
	}

	//---- update node file ----

	str_ptr = Get_Control_String (UPDATE_NODE_FILE);

	if (str_ptr != NULL) {
		update_flag = update_node_flag = true;
		Print (1);
		update_node_file.File_Type ("Update Node File");

		if (!update_node_file.Open (Project_Filename (str_ptr))) {
			Error ("Opening %s", update_node_file.File_Type ());
		}
	}

	//---- update link range ----

	str_ptr = Get_Control_String (UPDATE_LINK_RANGE);

	if (str_ptr != NULL) {
		update_flag = true;
		Print (2, "Update Link Range = %s", str_ptr);

		if (!update_links.Add_Ranges (str_ptr)) {
			Error ("Adding Update Links");
		}
	}

	//---- update link file ----

	str_ptr = Get_Control_String (UPDATE_LINK_FILE);

	if (str_ptr != NULL) {
		update_flag = update_link_flag = true;
		Print (1);
		update_link_file.File_Type ("Update Link File");

		if (!update_link_file.Open (Project_Filename (str_ptr))) {
			Error ("Opening %s", update_link_file.File_Type ());
		}
	}

	//---- delete node range ----

	str_ptr = Get_Control_String (DELETE_NODE_RANGE);

	if (str_ptr != NULL) {
		delete_flag = true;
		Print (2, "Delete Node Range = %s", str_ptr);

		if (!delete_nodes.Add_Ranges (str_ptr)) {
			Error ("Adding Delete Nodes");
		}
	}

	//---- delete node file ----

	str_ptr = Get_Control_String (DELETE_NODE_FILE);

	if (str_ptr != NULL) {
		delete_flag = delete_node_flag = true;
		Print (1);
		delete_node_file.File_Type ("Delete Node File");

		if (!delete_node_file.Open (Project_Filename (str_ptr))) {
			Error ("Opening %s", delete_node_file.File_Type ());
		}
	}

	//---- delete link range ----

	str_ptr = Get_Control_String (DELETE_LINK_RANGE);

	if (str_ptr != NULL) {
		delete_flag = true;
		Print (2, "Delete Link Range = %s", str_ptr);

		if (!delete_links.Add_Ranges (str_ptr)) {
			Error ("Adding Delete Links");
		}
	}

	//---- delete link file ----

	str_ptr = Get_Control_String (DELETE_LINK_FILE);

	if (str_ptr != NULL) {
		delete_flag = delete_link_flag = true;
		Print (1);
		delete_link_file.File_Type ("Delete Link File");

		if (!delete_link_file.Open (Project_Filename (str_ptr))) {
			Error ("Opening %s", delete_link_file.File_Type ());
		}
	}

	//---- link detail file ----

	str_ptr = Get_Control_String (LINK_DETAIL_FILE);

	if (str_ptr != NULL) {
		Print (1);
		detail_flag = true;

		if (!detail_file.Open (Project_Filename (str_ptr))) {
			Error ("Opening %s", detail_file.File_Type ());
		}
		lane_use_flag = Network_File_Flag (NEW_LANE_USE);
	}

	//---- get the projection data ----

	projection.Read_Control ();

	coord.Set_Projection (projection.Input_Projection (), projection.Output_Projection ());

	Set_Projection (&coord);

	return;

	//---- error message ----

control_error:
	Error ("Missing Control Key = %s", Current_Key ());

type_error:
	Error ("Adding Area Type Record");
}