static void parse_geom_triangle( const MaterialMap& matmap, const TriVertMap& tvmap, BodyMap& bodies, Physics* phys, const TiXmlElement* elem, Triangle* geom ) { parse_geom_base( matmap, elem, geom ); const TiXmlElement* child = elem->FirstChildElement( STR_VERTEX ); size_t count = 0; while ( child ) { if ( count > 2 ) { print_error_header( child ); std::cout << "To many vertices for triangle.\n"; throw std::exception(); } parse_lookup_data( tvmap, child, STR_NAME, &geom->vertices[count] ); child = child->NextSiblingElement( STR_VERTEX ); count++; } if ( count < 2 ) { print_error_header( elem ); std::cout << "To few vertices for triangle.\n"; throw std::exception(); } child = elem->FirstChildElement( STR_BODY ); if ( child ) { TriangleBody* body = new TriangleBody(geom); check_mem( body ); parse_trianglebody( child, body ); bodies[body->id] = body; phys->add_triangle(body); } }
static void parse_geom_triangle( const MaterialMap& matmap, const TriVertMap& tvmap, const TiXmlElement* elem, Triangle* geom ) { parse_geom_base( matmap, elem, geom ); const TiXmlElement* child = elem->FirstChildElement( STR_VERTEX ); size_t count = 0; while ( child ) { if ( count > 2 ) { print_error_header( child ); std::cout << "To many vertices for triangle.\n"; throw std::exception(); } parse_lookup_data( tvmap, child, STR_NAME, &geom->vertices[count] ); child = child->NextSiblingElement( STR_VERTEX ); count++; } if ( count < 2 ) { print_error_header( elem ); std::cout << "To few vertices for triangle.\n"; throw std::exception(); } }
static void parse_attrib_float( const TiXmlElement* elem, bool required, const char* name, float* val ) { int rv = elem->QueryFloatAttribute( name, val ); if ( rv == TIXML_WRONG_TYPE ) { print_error_header( elem ); std::cout << "error parsing '" << name << "'.\n"; throw std::exception(); } else if ( required && rv == TIXML_NO_ATTRIBUTE ) { print_error_header( elem ); std::cout << "missing '" << name << "'.\n"; throw std::exception(); } }
int option_parser::parse_long_option(int argc, char * argv[], int argi) { std::string argument(argv[argi] + 2); auto delimiter = argument.find(PARSE_OPTION_VALUE_DELIMITER); // argument has format --option=value. if (delimiter != std::string::npos) { std::string name = argument.substr(0, delimiter); std::string value = argument.substr(delimiter + 1); auto option_it = long_options_.find(name); if (option_it == long_options_.end()) { print_error_header(argc, argv, argi, 2, "uknown option"); return PARSE_ERROR; } option_it->second->mark(); if (option_it->second->size() == 0) { print_error_header(argc, argv, argi, 2, "option doesn't have value"); return PARSE_ERROR; } if (!option_it->second->parse_value(value)) { print_error_header(argc, argv, argi, name.length() + 3, "failed to parse argument"); return PARSE_ERROR; } return argi + 1; } // argument has format --option. auto option_it = long_options_.find(argument); if (option_it == long_options_.end()) { print_error_header(argc, argv, argi, 2, "uknown option"); return PARSE_ERROR; } option_it->second->mark(); if (!option_it->second->empty()) { return parse_option_value(argc, argv, argi, argument.size() + 2, option_it->second); } return argi + 1; }
static void parse_attrib_string( const TiXmlElement* elem, bool required, const char* name, const char** val ) { const char* att = elem->Attribute( name ); if ( !att && required ) { print_error_header( elem ); std::cout << "missing '" << name << "'.\n"; throw std::exception(); } else if ( att ) { *val = att; } }
static const TiXmlElement* get_unique_child( const TiXmlElement* parent, bool required, const char* name ) { const TiXmlElement* elem = parent->FirstChildElement( name ); if ( !elem ) { if ( required ) { print_error_header( parent ); std::cout << "no '" << name << "' defined.\n"; throw std::exception(); } else { return 0; } } if ( elem->NextSiblingElement( name ) ) { print_error_header( elem ); std::cout << "'" << name << "' multiply defined.\n"; throw std::exception(); } return elem; }
static void parse_lookup_data( const std::map< const char*, T, StrCompare > tmap, const TiXmlElement* elem, const char* name, T* val ) { typename std::map< const char*, T, StrCompare >::const_iterator iter; const char* att; parse_attrib_string( elem, true, name, &att ); iter = tmap.find( att ); if ( iter == tmap.end() ) { print_error_header( elem ); std::cout << "No such " << name << " '" << att << "'.\n"; throw std::exception(); } *val = iter->second; }
static void print_parse_error_header (void) { print_error_header(); if (original_file_name[0] != '\0' || file_name[0] != '\0') fprintf(stderr, "%s:", (original_file_name[0] != '\0') ? original_file_name : file_name); if (original_line_number != 0 || line_number != 0) fprintf(stderr, "%d:", (original_line_number != 0) ? original_line_number : line_number); fprintf(stderr, " "); }
int error (const char *format, ...) { va_list args; print_error_header(); fprintf(stderr, "error: "); va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); exit(EXIT_FAILURE); }
int calling_error (const char *format, ...) { va_list args; print_error_header(); fprintf(stderr, "calling error: "); va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); fprintf(stderr, "Usage: %s [options] layer_name[.%s]\n", program_name, program_name); fprintf(stderr, "For more information, type: %s --help\n", program_name); exit(EXIT_FAILURE); }
int warning (int priority, const char *format, ...) { va_list args; assert(priority != 0); assert(min_warning_priority != 0); if (priority >= min_warning_priority) { print_error_header(); fprintf(stderr, "warning: "); va_start(args, format); vfprintf(stderr, format, args); va_end(args); fprintf(stderr, "\n"); } return(0); }
int option_parser::parse_short_options(int argc, char * argv[], int argi) { std::string argument(argv[argi]); for (size_t i = 1; i < argument.size(); ++i) { auto option_iterator = short_options_.find(argument[i]); if (option_iterator == short_options_.end()) { print_error_header(argc, argv, argi, i, "uknown option"); return PARSE_ERROR; } option_iterator->second->mark(); if (!option_iterator->second->empty()) { return parse_option_value(argc, argv, argi, i + 1, option_iterator->second); } } return argi + 1; }
bool load_scene( Scene* scene, const char* filename ) { TiXmlDocument doc( filename ); const TiXmlElement* root = 0; const TiXmlElement* elem = 0; MaterialMap materials; MeshMap meshes; TriVertMap triverts; assert( scene ); // load the document if ( !doc.LoadFile() ) { std::cout << "ERROR, " << doc.ErrorRow() << ":" << doc.ErrorCol() << "; " << "parse error: " << doc.ErrorDesc() << "\n"; return false; } // check for root element root = doc.RootElement(); if ( !root ) { std::cout << "No root element.\n"; return false; } // reset the scene scene->reset(); try { // parse the camera elem = get_unique_child( root, true, STR_CAMERA ); parse_camera( elem, &scene->camera ); // parse background color parse_elem( root, true, STR_BACKGROUND, &scene->background_color ); // parse refractive index parse_elem( root, true, STR_REFRACT, &scene->refractive_index ); // parse ambient light parse_elem( root, false, STR_AMLIGHT, &scene->ambient_light ); // parse the lights elem = root->FirstChildElement( STR_PLIGHT ); while ( elem ) { PointLight pl; parse_point_light( elem, &pl ); scene->add_light( pl ); elem = elem->NextSiblingElement( STR_PLIGHT ); } // parse the materials elem = root->FirstChildElement( STR_MATERIAL ); while ( elem ) { Material* mat = new Material(); check_mem( mat ); scene->add_material( mat ); const char* name = parse_material( elem, mat ); assert( name ); // place each material in map by it's name, so we can associate geometries // with them when loading geometries // check for repeat name if ( !materials.insert( std::make_pair( name, mat ) ).second ) { print_error_header( elem ); std::cout << "Material '" << name << "' multiply defined.\n"; throw std::exception(); } elem = elem->NextSiblingElement( STR_MATERIAL ); } // parse the meshes elem = root->FirstChildElement( STR_MESH ); while ( elem ) { Mesh* mesh = new Mesh(); check_mem( mesh ); scene->add_mesh( mesh ); const char* name = parse_mesh( elem, mesh ); assert( name ); // place each mesh in map by it's name, so we can associate geometries // with them when loading geometries if ( !meshes.insert( std::make_pair( name, mesh ) ).second ) { print_error_header( elem ); std::cout << "Mesh '" << name << "' multiply defined.\n"; throw std::exception(); } elem = elem->NextSiblingElement( STR_MESH ); } // parse vertices (used by triangles) elem = root->FirstChildElement( STR_VERTEX ); while ( elem ) { Triangle::Vertex v; const char* name = parse_triangle_vertex( materials, elem, &v ); assert( name ); // place each vertex in map by it's name, so we can associate triangles // with them when loading geometries if ( !triverts.insert( std::make_pair( name, v ) ).second ) { print_error_header( elem ); std::cout << "Triangle vertex '" << name << "' multiply defined.\n"; throw std::exception(); } elem = elem->NextSiblingElement( STR_VERTEX ); } // parse the geometries // spheres elem = root->FirstChildElement( STR_SPHERE ); while ( elem ) { Sphere* geom = new Sphere(); check_mem( geom ); scene->add_geometry( geom ); parse_geom_sphere( materials, elem, geom ); elem = elem->NextSiblingElement( STR_SPHERE ); } // triangles elem = root->FirstChildElement( STR_TRIANGLE ); while ( elem ) { Triangle* geom = new Triangle(); check_mem( geom ); scene->add_geometry( geom ); parse_geom_triangle( materials, triverts, elem, geom ); elem = elem->NextSiblingElement( STR_TRIANGLE ); } // models elem = root->FirstChildElement( STR_MODEL ); while ( elem ) { Model* geom = new Model(); check_mem( geom ); scene->add_geometry( geom ); parse_geom_model( materials, meshes, elem, geom ); elem = elem->NextSiblingElement( STR_MODEL ); } // TODO add you own geometries here } catch ( std::bad_alloc const& ) { std::cout << "Out of memory error while loading scene\n."; scene->reset(); return false; } catch ( ... ) { scene->reset(); return false; } return true; }
int option_parser::parse_option_value(int argc, char * argv[], int argi, int index, option * operand) { std::string argument(argv[argi]); // parsing options of type --option=value (-o=value). if (index < static_cast<int>(argument.size())) { if (argument[index] != PARSE_OPTION_VALUE_DELIMITER) { print_error_header(argc, argv, argi, index, "option value expected"); return PARSE_ERROR; } std::string option_value = argument.substr(index + 1); if (!operand->parse_value(option_value)) { print_error_header(argc, argv, argi, index + 1, "failed to parse value or restriction does not accept it"); return PARSE_ERROR; } return argi + 1; } // parsing option of type --option value1 value2 ... (-o value1 value2 ...). ++argi; size_type parsed = 0; const size_type max_values = operand->size(); for (; argi < argc; ++argi, ++parsed) { // everything is already parsed. if (parsed == max_values) { break; } // we have another option or delimiter. if (type(argv[argi]) != ARGUMENT) { break; } // parse argument. if (!operand->parse_value(argv[argi])) { print_error_header(argc, argv, argi, 0, "failed to parse value or restriction does not accept it"); return PARSE_ERROR; } } if ((parsed == 0) && (operand->value_category() == REQUIRED)) { print_error_header(argc, argv, argi - 1, index, "option has required value"); return PARSE_ERROR; } return argi; }