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); }
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); }
/************************************************************************* * * 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; }
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; }
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); }
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); }
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); }
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; }
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); } }
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; }
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); }
/************************************************************************* * * 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; }
/************************************************************************* * * 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() */
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"); }
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); }
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"); }