diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/model/Typesystem.cpp | 79 | ||||
| -rw-r--r-- | src/core/model/Typesystem.hpp | 74 | 
2 files changed, 107 insertions, 46 deletions
diff --git a/src/core/model/Typesystem.cpp b/src/core/model/Typesystem.cpp index 7dd5613..a3c5b6d 100644 --- a/src/core/model/Typesystem.cpp +++ b/src/core/model/Typesystem.cpp @@ -67,10 +67,7 @@ bool Type::build(Variant &data, Logger &logger) const  	return build(data, logger, NullMagicCallback);  } -bool Type::doCheckIsa(Handle<const Type> type) const -{ -	return false; -} +bool Type::doCheckIsa(Handle<const Type> type) const { return false; }  bool Type::checkIsa(Handle<const Type> type) const  { @@ -114,6 +111,11 @@ bool StringType::doBuild(Variant &data, Logger &logger,  /* Class EnumType */ +EnumType::EnumType(Manager &mgr, std::string name, Handle<Typesystem> system) +    : Type(mgr, std::move(name), system, false), nextOrdinalValue(0) +{ +} +  bool EnumType::doBuild(Variant &data, Logger &logger,                         const MagicCallback &magicCallback) const  { @@ -145,32 +147,45 @@ bool EnumType::doBuild(Variant &data, Logger &logger,  	throw LoggableException{"Expected integer or identifier", data};  } -Rooted<EnumType> EnumType::createValidated( -    Manager &mgr, std::string name, Handle<Typesystem> system, -    const std::vector<std::string> &values, Logger &logger) -{ -	// Map used to store the unique values of the enum -	std::map<std::string, Ordinal> unique_values; - -	// The given vector may not be empty +bool EnumType::doValidate(Logger &logger) const{ +	bool ok = true;  	if (values.empty()) { -		logger.error("Enumeration constants may not be empty."); +		logger.error("Enum type must have at least one entry", *this); +		ok = false;  	} +	return ok & validateName(logger); +} -	// Iterate over the input vector, check the constant names for validity and -	// uniqueness and insert them into the internal values map -	for (size_t i = 0; i < values.size(); i++) { -		if (!Utils::isIdentifier(values[i])) { -			logger.error(std::string("\"") + values[i] + -			             "\" is no valid identifier."); -		} +void EnumType::addEntry(const std::string &entry, Logger &logger) +{ +	if (!Utils::isIdentifier(entry)) { +		logger.error(std::string("\"") + entry + +		             "\" is not a valid identifier."); +		return; +	} -		if (!(unique_values.insert(std::make_pair(values[i], i))).second) { -			logger.error(std::string("The value ") + values[i] + -			             " was duplicated."); -		} +	if (!values.emplace(entry, nextOrdinalValue).second) { +			logger.error(std::string("The enumeration entry ") +entry + +			             std::string(" was duplicated")); +			return; +	} +	nextOrdinalValue++; +} + +void EnumType::addEntries(const std::vector<std::string> &entries, Logger &logger) +{ +	for (const std::string &entry: entries) { +		addEntry(entry, logger);  	} -	return new EnumType{mgr, name, system, unique_values}; +} + +Rooted<EnumType> EnumType::createValidated( +    Manager &mgr, std::string name, Handle<Typesystem> system, +    const std::vector<std::string> &entries, Logger &logger) +{ +	Rooted<EnumType> type = new EnumType{mgr, name, system}; +	type->addEntries(entries, logger); +	return type;  }  std::string EnumType::nameOf(Ordinal i) const @@ -390,12 +405,15 @@ bool StructType::buildFromMap(Variant &data, Logger &logger,  			ok = false;  			logger.error(std::string("Invalid attribute key \"") + key +  			                 std::string("\""), -			             value); +			             data);  		}  	}  	// Copy the built array to the result and insert missing default values +	// TODO: Nicer way of assigning a new variant value and keeping location? +	SourceLocation loc = data.getLocation();  	data = arr; +	data.setLocation(loc);  	return insertDefaults(data, set, logger) && ok;  } @@ -470,7 +488,6 @@ bool StructType::doCheckIsa(Handle<const Type> type) const  	return false;  } -  Rooted<StructType> StructType::createValidated(      Manager &mgr, std::string name, Handle<Typesystem> system,      Handle<StructType> parentStructure, const NodeVector<Attribute> &attributes, @@ -625,7 +642,6 @@ bool ArrayType::doCheckIsa(Handle<const Type> type) const  	return t1->checkIsa(t2);  } -  /* Class UnknownType */  bool UnknownType::doBuild(Variant &, Logger &, const MagicCallback &) const @@ -706,6 +722,13 @@ Rooted<StructType> Typesystem::createStructType(const std::string &name)  	return structType;  } +Rooted<EnumType> Typesystem::createEnumType(const std::string &name) +{ +	Rooted<EnumType> enumType{new EnumType(getManager(), name, this)}; +	addType(enumType); +	return enumType; +} +  Rooted<Constant> Typesystem::createConstant(const std::string &name,                                              Variant value)  { diff --git a/src/core/model/Typesystem.hpp b/src/core/model/Typesystem.hpp index 7581626..819f90d 100644 --- a/src/core/model/Typesystem.hpp +++ b/src/core/model/Typesystem.hpp @@ -371,26 +371,16 @@ public:  private:  	/** -	 * Map containing the enumeration type values and the associated integer -	 * representation. +	 * Value holding the next ordinal value that is to be used when adding a new +	 * type.  	 */ -	const std::map<std::string, Ordinal> values; +	Ordinal nextOrdinalValue;  	/** -	 * Private constructor of the EnumType class used to create a new EnumType -	 * instance from a previously created name to value map. The parameters are -	 * not checked for validity. -	 * -	 * @param mgr is the underlying Manager instance. -	 * @param name is the name of the EnumType instance. Should be a valid -	 * identifier. -	 * @param values is a vector containing the enumeration type constants. +	 * Map containing the enumeration type values and the associated integer +	 * representation.  	 */ -	EnumType(Manager &mgr, std::string name, Handle<Typesystem> system, -	         std::map<std::string, Ordinal> values) -	    : Type(mgr, std::move(name), system, false), values(std::move(values)) -	{ -	} +	std::map<std::string, Ordinal> values;  protected:  	/** @@ -405,22 +395,61 @@ protected:  	bool doBuild(Variant &data, Logger &logger,  	             const MagicCallback &magicCallback) const override; +	/** +	 * Returns true if the internal value list is non-empty. +	 * +	 * @param logger is the logger instance to which validation errors are +	 * logged. +	 */ +	bool doValidate(Logger &logger) const override; +  public:  	/** +	 * Constructor of the EnumType class. +	 * +	 * @param mgr is the underlying Manager instance. +	 * @param name is the name of the EnumType instance. Should be a valid +	 * identifier. +	 * @param system is the parent typesystem. +	 */ +	EnumType(Manager &mgr, std::string name, Handle<Typesystem> system); + +	/** +	 * Adds a new entry to the enum. The enum element is validated, errors +	 * are logged in the given logger instance. +	 * +	 * @param entry is the name of the enum element that should be added. +	 * @param logger is the logger instance that should be used to write error +	 * messages. +	 */ +	void addEntry(const std::string &entry, Logger &logger); + +	/** +	 * Adds a new entry to the enum. The enum element is validated, errors +	 * are logged in the given logger instance. +	 * +	 * @param entires is a list containing the enum elements that should be +	 * added. +	 * @param logger is the logger instance that should be used to write error +	 * messages. +	 */ +	void addEntries(const std::vector<std::string> &entries, Logger &logger); + +	/**  	 * Creates a new enum instance and validates the incomming value vector.  	 *  	 * @param mgr is the underlying Manager instance.  	 * @param name is the name of the EnumType instance. Should be a valid  	 * identifier.  	 * @param system is a reference to the parent Typesystem instance. -	 * @param values is a vector containing the enumeration type constants. +	 * @param entries is a vector containing the enumeration type constants.  	 * The constants are checked for validity (must be a valid identifier) and  	 * uniqueness (each value must exist exactly once).  	 * @param logger is the Logger instance into which errors should be written.  	 */  	static Rooted<EnumType> createValidated(  	    Manager &mgr, std::string name, Handle<Typesystem> system, -	    const std::vector<std::string> &values, Logger &logger); +	    const std::vector<std::string> &entries, Logger &logger);  	/**  	 * Creates a Variant containing a valid representation of a variable of this @@ -1135,6 +1164,15 @@ public:  	Rooted<StructType> createStructType(const std::string &name);  	/** +	 * Creates a new EnumType instance with the given name. Adds the new +	 * EnumType as member to the typesystem. +	 * +	 * @param name is the name of the structure that should be created. +	 * @return the new EnumType instance. +	 */ +	Rooted<EnumType> createEnumType(const std::string &name); + +	/**  	 * Creates a new Constant instance with the given name. Adds the new  	 * Constant as member to the typesystem.  	 *  | 
