1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
12 ******************************************************************************/
13 #include "AttributeType.hh"
15 AttributeType::AttributeType(ComplexType
* a_complexType
)
16 : SimpleType(a_complexType
->getParser(), a_complexType
->getModule(), c_unknown
)
19 , nameSpace(empty_string
)
21 , origModule(a_complexType
->getModule()) {
22 parent
= a_complexType
;
25 AttributeType::AttributeType(const AttributeType
& other
)
27 , isAnyAttr(other
.isAnyAttr
)
28 , useVal(other
.useVal
)
29 , nameSpace(other
.nameSpace
)
31 , origModule(other
.getModule()) {
34 AttributeType::~AttributeType() {
38 void AttributeType::modifyValues() {
39 if (parser
->getActualTagName() == n_attribute
|| parser
->getActualTagName() == n_anyAttribute
) {
40 ((ComplexType
*) parent
)->modifyAttributeParent();
44 void AttributeType::setTypeOfField(const Mstring
& in
) {
48 void AttributeType::setNameOfField(const Mstring
& in
) {
52 void AttributeType::setToAnyAttribute() {
56 void AttributeType::setFieldPath(const Mstring path
) {
58 actualPath
= getName().convertedValue
;
60 if ((parent
->getMinOccurs() != 1 || parent
->getMaxOccurs() != 1) && parent
->getName().list_extension
) {
61 actualPath
= path
+ Mstring("[-].") + getName().convertedValue
;
63 actualPath
= path
+ Mstring(".") + getName().convertedValue
;
68 void AttributeType::collectVariants(List
<Mstring
>& container
) {
70 if (variant
.empty() && hidden_variant
.empty()) {
78 enumeration
.insertVariants();
80 for (List
<Mstring
>::iterator var2
= variant
.end(); var2
; var2
= var2
->Prev
) {
81 container
.push_back(Mstring("variant (") + actualPath
+ Mstring(") ") + Mstring(var2
->Data
.c_str()) + Mstring(";\n"));
83 for (List
<Mstring
>::iterator hidden_var
= hidden_variant
.end(); hidden_var
; hidden_var
= hidden_var
->Prev
) {
84 container
.push_back(Mstring("//variant (") + actualPath
+ Mstring(") ") + Mstring(hidden_var
->Data
.c_str()) + Mstring(";\n"));
88 void AttributeType::nameConversion_names(QualifiedNames
& used_ns
) {
89 //Do not convert invisible field names
90 if (!visible
|| useVal
== prohibited
) {
93 Mstring res
, var(module
->getTargetNamespace());
94 QualifiedNames used_names
= TTCN3ModuleInventory::getInstance().getTypenames();
95 for (QualifiedNames::iterator n
= used_ns
.begin(); n
; n
= n
->Next
) {
96 used_names
.push_back(n
->Data
);
99 if(!used_names
.empty()){
100 q
= used_names
.back();
102 q
= QualifiedName(empty_string
, empty_string
);
104 XSDName2TTCN3Name(name
.convertedValue
, used_names
, field_name
, res
, var
);
105 name
.convertedValue
= res
;
106 addVariant(V_onlyValue
, var
);
107 if (q
.name
!= used_names
.back().name
) {
108 //If the name is converted then push to the used names list
109 used_ns
.push_back(used_names
.back());
112 for (List
<SimpleType
*>::iterator st
= nameDepList
.begin(); st
; st
= st
->Next
) {
113 st
->Data
->setTypeValue(res
);
117 void AttributeType::applyUseAttribute() {
136 isOptional
= isOptional
|| (minOccurs
== 0 && maxOccurs
== 1);
139 void AttributeType::applyNamespaceAttribute(VariantMode varLabel
) {
140 List
<Mstring
> namespaces
;
141 if (!nameSpace
.empty()) {
142 expstring_t valueToSplitIntoTokens
= mcopystr(nameSpace
.c_str());
144 token
= strtok(valueToSplitIntoTokens
, " ");
145 while (token
!= NULL
) {
146 namespaces
.push_back(Mstring(token
));
147 token
= strtok(NULL
, " ");
149 Free(valueToSplitIntoTokens
);
154 // Note: libxml2 will verify the namespace list according to the schema
155 // of XML Schema. It is either ##any, ##other, ##local, ##targetNamespace,
156 // or a list of (namespace reference | ##local | ##targetNamespace).
157 for (List
<Mstring
>::iterator ns
= namespaces
.begin(); ns
; ns
= ns
->Next
) {
158 static const Mstring
xxany("##any"), xxother("##other"), xxlocal("##local"),
159 xxtargetNamespace("##targetNamespace");
160 if (!first
) any_ns
+= ", ";
162 if (ns
->Data
== xxany
) {
163 }// this must be the only element, nothing to add
164 else if (ns
->Data
== xxother
) { // this must be the only element
165 if(first
){ any_ns
+= " except "; }
166 any_ns
+= "unqualified";
167 if (module
->getTargetNamespace() != "NoTargetNamespace") {
169 any_ns
+= parent
->getModule()->getTargetNamespace();
172 }// The three cases below can happen multiple times
174 if (first
) any_ns
+= " from ";
175 // else a comma was already added
176 if (ns
->Data
== xxtargetNamespace
) {
178 any_ns
+= parent
->getModule()->getTargetNamespace();
180 } else if (ns
->Data
== xxlocal
) {
181 any_ns
+= "unqualified";
188 if(!first
|| ns
->Data
!= xxany
){
193 addVariant(varLabel
, any_ns
, true);
196 void AttributeType::applyMinMaxOccursAttribute(unsigned long long min
, unsigned long long max
) {
201 void AttributeType::dump(unsigned int depth
) const {
202 fprintf(stderr
, "%*s %sField '%s' -> '%s' at %p\n", depth
* 2, "", isVisible() ? "" : "(hidden)",
203 name
.originalValueWoPrefix
.c_str(), name
.convertedValue
.c_str(), (const void*) this);
204 fprintf(stderr
, "%*s %s Type: \n", depth
* 2, "", type
.convertedValue
.c_str());
205 fprintf(stderr
, "%*s type %s \n", (depth
+ 1) * 2, "", type
.convertedValue
.c_str());
206 fprintf(stderr
, "%*s (%llu .. %llu)\n", (depth
+ 1) * 2, "", minOccurs
, maxOccurs
);
207 fprintf(stderr
, "%*s %d variants: ", (depth
+ 1) * 2, "", (int) variant
.size());
208 for (List
<Mstring
>::iterator var
= variant
.begin(); var
; var
= var
->Next
) {
209 fprintf(stderr
, "%s, ", var
->Data
.c_str());
211 fprintf(stderr
, "\n%*s path =/%s/", (depth
+ 1) * 2, "", actualPath
.c_str());
214 void AttributeType::printToFile(FILE* file
, unsigned level
) {
218 printComment(file
, level
);
220 if(enumeration
.modified
&& hasVariant(Mstring("\"list\""))){
221 printMinOccursMaxOccurs(file
, false);
222 fprintf(file
, "enumerated {\n");
223 enumeration
.sortFacets();
224 enumeration
.printToFile(file
);
226 fprintf(file
, "\n} %s", name
.convertedValue
.c_str());
227 } else if (enumeration
.modified
) {
228 if (isFloatType(builtInBase
)) {
229 fprintf(file
, "%s %s (", type
.convertedValue
.c_str(), name
.convertedValue
.c_str());
230 enumeration
.sortFacets();
231 enumeration
.printToFile(file
);
234 fprintf(file
, "enumerated {\n");
235 enumeration
.sortFacets();
236 enumeration
.printToFile(file
);
239 fprintf(file
, "} %s", name
.convertedValue
.c_str());
242 printMinOccursMaxOccurs(file
, false);
243 int multiplicity
= multi(module
, getReference(), this);
244 if ((multiplicity
> 1) && getReference().get_ref()) {
245 fprintf(file
, "%s.", getReference().get_ref()->getModule()->getModulename().c_str());
247 fprintf(file
, "%s %s", type
.convertedValue
.c_str(), name
.convertedValue
.c_str());
248 getPattern().printToFile(file
);
249 getValue().printToFile(file
);
250 getLength().printToFile(file
);
252 if (isOptional
|| isAnyAttr
) {
253 fprintf(file
, " optional");