Ejemplo n.º 1
0
// Pop the children from the stack and
// check for correct type and sequence of children
static void XMLCALL endElement(void *context, const char *elm) {
    Elm el;
    el = checkElement(elm);
    assert((el >= elm_fmiModelDescription) && (el <=elm_Enumeration));
    switch(el) {
        case elm_fmiModelDescription: 
            {
                 ModelDescription* md;
                 ListElement** ud = NULL;     // NULL or list of BaseUnits
                 Type**        td = NULL;     // NULL or list of Types 
                 Element*      de = NULL;     // NULL or DefaultExperiment
                 ListElement** va = NULL;     // NULL or list of Tools
                 ScalarVariable** mv = NULL;  // NULL or list of ScalarVariable
                 ListElement* child;

                 child = checkPop(ANY_TYPE);
                 if (child->type == elm_ModelVariables){
                     mv = (ScalarVariable**)child->list;
                     free(child);
                     child = checkPop(ANY_TYPE);
                     if (!child) return;
                 }
                 if (child->type == elm_VendorAnnotations){
                     va = (ListElement**)child->list;
                     free(child);
                     child = checkPop(ANY_TYPE);
                     if (!child) return;
                 }
                 if (child->type == elm_DefaultExperiment){
                     de = (Element*)child;
                     child = checkPop(ANY_TYPE);
                     if (!child) return;
                 }
                 if (child->type == elm_TypeDefinitions){
                     td = (Type**)child->list;
                     free(child);
                     child = checkPop(ANY_TYPE);
                     if (!child) return;
                 }
                 if (child->type == elm_UnitDefinitions){
                     ud = (ListElement**)child->list;
                     free(child);
                     child = checkPop(ANY_TYPE);
                     if (!child) return;
                 }
                 if (!checkElementType(child, elm_fmiModelDescription)) return;
                 md = (ModelDescription*)child;
                 md->modelVariables = mv;
                 md->vendorAnnotations = va;
                 md->defaultExperiment = de;
                 md->typeDefinitions = td;
                 md->unitDefinitions = ud;
                 stackPush(stack, md);
                 break;
            }
        case elm_Type:
            {
                Type* tp;
                Element* ts = checkPop(ANY_TYPE);
                if (!ts) return;
                if (!checkPeek(elm_Type)) return;
                tp = (Type*)stackPeek(stack);
                switch (ts->type) {
                    case elm_RealType:
                    case elm_IntegerType:
                    case elm_BooleanType:
                    case elm_EnumerationType:
                        break;
                    default:
                         logFatalTypeError("RealType or similar", ts->type);
                         return;
                }
                tp->typeSpec = ts;
                break;
            }
        case elm_ScalarVariable:
            {
                ScalarVariable* sv;
                Element** list = NULL;
                Element* child = checkPop(ANY_TYPE);
                if (!child) return;
                if (child->type==elm_DirectDependency){
                    list = ((ListElement*)child)->list;
                    free(child);
                    child = checkPop(ANY_TYPE);
                    if (!child) return;
                }
                if (!checkPeek(elm_ScalarVariable)) return;
                sv = (ScalarVariable*)stackPeek(stack);
                switch (child->type) {
                    case elm_Real:
                    case elm_Integer:
                    case elm_Boolean:
                    case elm_Enumeration:
                        break;
                    default:
                         logFatalTypeError("Real or similar", child->type);
                         return;
                }
                sv->directDependencies = list;
                sv->typeSpec = child;
                break;
            }
        case elm_ModelVariables:    popList(elm_ScalarVariable); break;
        case elm_VendorAnnotations: popList(elm_Tool);break;
        case elm_Tool:              popList(elm_Annotation); break;
        case elm_TypeDefinitions:   popList(elm_Type); break;
        case elm_EnumerationType:   popList(elm_Item); break;
        case elm_UnitDefinitions:   popList(elm_BaseUnit); break;
        case elm_BaseUnit:          popList(elm_DisplayUnitDefinition); break;
        case elm_DirectDependency:  popList(elm_Name); break;
        case elm_Name:
            {
                 // Exception: the name value is represented as element content.
                 // All other values of the XML file are represented using attributes.
                 Element* name = checkPop(elm_Name);
                 if (!name) return;
                 name->n = 2;
                 name->attributes = malloc(2*sizeof(char*));
                 name->attributes[0] = attNames[att_input];
                 name->attributes[1] = data;
                 data = NULL;
                 skipData = 1; // stop recording element content
                 stackPush(stack, name);
                 break;
            }
        default: // must be a leaf Element
                 assert(getAstNodeType(el)==astElement);
                 break;
    }
    // All children of el removed from the stack.
    // The top element must be of type el now.
    checkPeek(el);
}
Ejemplo n.º 2
0
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Pop the children from the stack and check for correct type and sequence of children
/// This is the end handler of parser. The parser ends here.
///
///\param context
///\param elm 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void XMLCALL endElement(void *context, const char *elm) {
    Elm el;
    el = checkElement(elm);
    printfDebug(" **** ending element %s.\n", elmNames[el]);
    switch(el) {        
        case elm_fmiModelDescription: 
            {
                 ModelDescription* md;
                 ListElement** im = NULL;  		//  NULL or list of CoSimulation_StandAlone under Implementation
                 ListElement** ud = NULL;     	//  NULL or list of BaseUnits under UnitDefinitions
                 Type**        td = NULL;     	//  NULL or list of Types under TypeDefinitions
                 Element*      de = NULL;     	// NULL or DefaultExperiment
                 ListElement** va = NULL;     	// NULL or list of Tools
                 ScalarVariable** mv = NULL;  	// NULL or list of ScalarVariables under ModelVariables
                 ListElement* child;
                 printDebug("$$$$$ entered endElement 'elm_fmiModelDescription'\n");
                 child = checkPop(ANY_TYPE); // get a child from stack

                 while (child && child->type != elm_fmiModelDescription)  // add while-loop in case the elements in the random order
                 {
					 if (child->type == elm_VendorAnnotations){
						 va = (ListElement**)child->list;    // VendorAnnotations (ListElement) contains Tool (ListElement))
						 free(child);
						 child = checkPop(ANY_TYPE);
						 if (!child) return;
					 }
					 if (child->type == elm_DefaultExperiment){
						 de = (Element*)child;				// DefaultExperiment (Element) with only attributes
						 child = checkPop(ANY_TYPE);
						 if (!child) return;
					 }
					 if (child->type == elm_TypeDefinitions){
						 td = (Type**)child->list;     		// TypeDefinitions (ListElement) contains Type (Type)
						 free(child);
						 child = checkPop(ANY_TYPE);
						 if (!child) return;
					 }
					 if (child->type == elm_UnitDefinitions){
						 ud = (ListElement**)child->list;   // UnitDefinitions (ListElement) contains BaseUnit (ListElement)
						 free(child);
						 child = checkPop(ANY_TYPE);
						 if (!child) return;
					 }
					 if (child->type == elm_Implementation){ 	// Implementation is listElement, it can be treated the same as UnitDefinitions
						 im = (ListElement**)child->list; 		// Implementation (Implementation) contains CoSimulation_StandAlone (ListElement)
						 free(child);							// Zuo:
						 child = checkPop(ANY_TYPE);			// Zuo:
						 if (!child) return;					// Zuo:
					 }											// Zuo:
					 if (child->type == elm_ModelVariables){
						  mv = (ScalarVariable**)child->list;  // ModelVariables (ListElement) contains ScalarVariable (ScalarVariable)
						  free(child);
						  child = checkPop(ANY_TYPE);
						  if (!child) return;
					 }
                 }
		         printDebug("$$$$$ checking element type \n");
                 if (checkElementType(child, elm_fmiModelDescription)) return;
                 printDebug("$$$$$ checked  element type \n");
                 md = (ModelDescription*)child;

                 // the following build the link of elements for ModelDescriptions
                 md->modelVariables = mv;
                 md->implementation = im; // added M. Wetter
                 md->vendorAnnotations = va;
                 md->defaultExperiment = de;
                 md->typeDefinitions = td;
                 md->unitDefinitions = ud;
                 printDebug("$$$$$ calling stackPush \n");
                 stackPush(stack, md);
                 printDebug("$$$$$ called stackPush \n");
                 break;
            }
        case elm_Type:
            {
                Type* tp;
                Element* ts = checkPop(ANY_TYPE);
                if (!ts) return;  // If there is no sub-element, return
                if (checkPeek(elm_Type)) return; // If the sub-element is not Type, return
                tp = (Type*)stackPeek(stack);  // Get the element
                switch (ts->type) {
                    case elm_RealType:
                    case elm_IntegerType:
                    case elm_BooleanType:
                    case elm_EnumerationType:
                    case elm_StringType:
                        break;
                    default: 		// Element type does not match
                         logFatalTypeError("RealType or similar", ts->type);
                         return;
                }
                tp->typeSpec = ts;  	// parent (tp) links to sub-element (ts)
                break;
            }
        case elm_ScalarVariable:
            {
                ScalarVariable* sv;
                Element** list = NULL;
                Element* child = checkPop(ANY_TYPE);
                if (!child) return;
                if (child->type==elm_DirectDependency){
                    list = ((ListElement*)child)->list; // DirectDependency is ListElement
                    free(child);
                    child = checkPop(ANY_TYPE);
                    if (!child) return;
                }
                if (checkPeek(elm_ScalarVariable)) return;  // If next element is not ScalarVariable, return
                sv = (ScalarVariable*)stackPeek(stack);
                switch (child->type) {
                    case elm_Real:
                    case elm_Integer:
                    case elm_Boolean:
                    case elm_Enumeration:
                    case elm_String:
                        break;
                    default:
                         logFatalTypeError("Real or similar", child->type);
                         return;
                }
                sv->directDependencies = list;
                sv->typeSpec = child;
                break;
            }
        case elm_Implementation:  	popList(elm_CoSimulation_StandAlone); break; // Needs to be modified if CoSimulation_Tool is added
	    case elm_CoSimulation_StandAlone:  popList(elm_Capabilities); break; // CoSimulation_StandAlone only has Capabilities
        case elm_ModelVariables:    popList(elm_ScalarVariable); break;
        case elm_VendorAnnotations: popList(elm_Tool);break;
        case elm_Tool:              popList(elm_Annotation); break;
        case elm_TypeDefinitions:   popList(elm_Type); break;
        case elm_EnumerationType:   popList(elm_Item); break;
        case elm_UnitDefinitions:   popList(elm_BaseUnit); break;
        case elm_BaseUnit:          popList(elm_DisplayUnitDefinition); break;
        case elm_DirectDependency:  popList(elm_Name); break;
        case elm_Name:
            {
                 // Exception: the name value is represented as element content.
                 // All other values of the XML file are represented using attributes.
                 Element* name = checkPop(elm_Name);
                 if (!name) return;
                 name->n = 2;
                 name->attributes = malloc(2*sizeof(char*));
                 name->attributes[0] = attNames[att_input];
                 name->attributes[1] = data;
                 data = NULL;
                 skipData = 1; // stop recording element content
                 stackPush(stack, name);
                 break;
            }
        case -1: return; // illegal element error
        default: // must be a leaf Element
				printDebug("+++++++ got a leaf element\n");
                assert(getAstNodeType(el)==astElement);
                break;
    }
    // All children of el removed from the stack.
    // The top element must be of type el now.
    checkPeek(el);
}