Project

General

Profile

Statistics
| Branch: | Revision:

root / src / nedxml / nedcrossvalidator.cc @ 79bb12dc

History | View | Annotate | Download (13.5 KB)

1 01873262 Georg Kunz
//==========================================================================
2
// nedcrossvalidator.cc - part of
3
//
4
//                     OMNeT++/OMNEST
5
//            Discrete System Simulation in C++
6
//
7
// Contents:
8
//   class NEDCrossValidator
9
//
10
//==========================================================================
11
12
/*--------------------------------------------------------------*
13
  Copyright (C) 2002-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19
20
#include "stringutil.h"
21
#include "nederror.h"
22
#include "nedexception.h"
23
#include "nedresourcecache.h"
24
#include "nedcrossvalidator.h"
25
26
USING_NAMESPACE
27
28
29
NEDCrossValidator::NEDCrossValidator(bool parsedExpr, NEDResourceCache *res, NEDErrorStore *e)
30
   : NEDValidatorBase(e)
31
{
32
    parsedExpressions = parsedExpr;
33
    resolver = res;
34
}
35
36
NEDCrossValidator::~NEDCrossValidator()
37
{
38
}
39
40
NEDElement *NEDCrossValidator::getXXXDeclaration(const char *name, int tagcode1, int tagcode2)
41
{
42
    NEDTypeInfo *component = resolver->lookup(name);
43
    if (!component)
44
        return NULL;
45
46
    int type = component->getTree()->getTagCode();
47
    if (type!=tagcode1 && type!=tagcode2)
48
        return NULL;
49
    return component->getTree();
50
}
51
52
NEDElement *NEDCrossValidator::getModuleDeclaration(const char *name)
53
{
54
    return getXXXDeclaration(name, NED_SIMPLE_MODULE, NED_COMPOUND_MODULE);
55
}
56
57
NEDElement *NEDCrossValidator::getChannelDeclaration(const char *name)
58
{
59
    return getXXXDeclaration(name, NED_CHANNEL);
60
}
61
62
NEDElement *NEDCrossValidator::getModuleInterfaceDeclaration(const char *name)
63
{
64
    return getXXXDeclaration(name, NED_MODULE_INTERFACE);
65
}
66
67
NEDElement *NEDCrossValidator::getChannelInterfaceDeclaration(const char *name)
68
{
69
    return getXXXDeclaration(name, NED_CHANNEL_INTERFACE);
70
}
71
72
NEDElement *NEDCrossValidator::getEnumDeclaration(const char *name)
73
{
74
    return getXXXDeclaration(name, NED_ENUM);
75
}
76
77
NEDElement *NEDCrossValidator::getClassDeclaration(const char *name)
78
{
79
    return getXXXDeclaration(name, NED_CLASS);
80
}
81
82
void NEDCrossValidator::validateElement(FilesElement *node)
83
{
84
}
85
86
void NEDCrossValidator::validateElement(NedFileElement *node)
87
{
88
}
89
90
void NEDCrossValidator::validateElement(CommentElement *node)
91
{
92
}
93
94
void NEDCrossValidator::validateElement(ImportElement *node)
95
{
96
}
97
98
void NEDCrossValidator::validateElement(PropertyDeclElement *node)
99
{
100
    // FIXME revise
101
}
102
103
void NEDCrossValidator::validateElement(ExtendsElement *node)
104
{
105
    // FIXME revise
106
}
107
108
void NEDCrossValidator::validateElement(InterfaceNameElement *node)
109
{
110
    // FIXME revise
111
}
112
113
void NEDCrossValidator::validateElement(SimpleModuleElement *node)
114
{
115
    // FIXME revise
116
    // make sure module type name does not exist yet
117
    if (getModuleDeclaration(node->getName()))
118
        errors->addError(node, "redefinition of module with name '%s'",node->getName());
119
}
120
121
void NEDCrossValidator::validateElement(ModuleInterfaceElement *node)
122
{
123
    // FIXME revise
124
}
125
126
void NEDCrossValidator::validateElement(CompoundModuleElement *node)
127
{
128
    // FIXME revise
129
    // make sure module type name does not exist yet
130
    if (getModuleDeclaration(node->getName()))
131
        errors->addError(node, "redefinition of module with name '%s'",node->getName());
132
}
133
134
void NEDCrossValidator::validateElement(ParametersElement *node)
135
{
136
    // FIXME revise
137
}
138
139
void NEDCrossValidator::validateElement(ParamElement *node)
140
{
141
    // FIXME code comes from substparamnode -- REVISE
142
    if (!moduletypedecl)
143
        return;
144
145
    // make sure parameter exists in module type
146
    const char *paramName = node->getName();
147
    NEDElement *params = moduletypedecl->getFirstChildWithTag(NED_PARAMETERS);
148
    if (!params || params->getFirstChildWithAttribute(NED_PARAM, "name", paramName)==NULL)
149
        {errors->addError(node, "module type '%s' has no parameter named '%s'", moduletypedecl->getAttribute("name"), paramName);return;}
150
151
    // TBD compile-time check for type mismatch
152
}
153
154
void NEDCrossValidator::validateElement(PropertyElement *node)
155
{
156
    // FIXME revise
157
}
158
159
void NEDCrossValidator::validateElement(PropertyKeyElement *node)
160
{
161
    // FIXME revise
162
}
163
164
void NEDCrossValidator::validateElement(GatesElement *node)
165
{
166
    // FIXME revise
167
}
168
169
void NEDCrossValidator::validateElement(GateElement *node)
170
{
171
    // FIXME the following lines come from gatesizenode -- REVISE!
172
    if (!moduletypedecl)
173
        return;
174
175
    // make sure gate exists in module type
176
    const char *gatename = node->getName();
177
    GatesElement *gatesdecl = (GatesElement *)moduletypedecl->getFirstChildWithTag(NED_GATES);
178
    if (!gatesdecl)
179
    {
180
        errors->addError(node, "module type does not have gates");
181
        return;
182
    }
183
    GateElement *gatedecl = (GateElement *)gatesdecl->getFirstChildWithAttribute(NED_GATE, "name", gatename);
184
    if (!gatedecl)
185
    {
186
        errors->addError(node, "module type does not have a gate named '%s'",gatename);
187
        return;
188
    }
189
190
    // check it is vector
191
//    if (!gatedecl->getIsVector())
192
//        errors->addError(node, "gate '%s' is not a vector gate",gatename);
193
}
194
195
void NEDCrossValidator::validateElement(TypesElement *node)
196
{
197
    // FIXME revise
198
}
199
200
void NEDCrossValidator::validateElement(SubmodulesElement *node)
201
{
202
    // FIXME revise
203
}
204
205
void NEDCrossValidator::validateElement(SubmoduleElement *node)
206
{
207
    // FIXME revise
208
    // make sure module type exists
209
    const char *type_name = node->getType();
210
    moduletypedecl = getModuleDeclaration(type_name);
211
    if (!moduletypedecl)
212
        errors->addError(node, "unknown module type '%s'",type_name);
213
}
214
215
void NEDCrossValidator::validateElement(ConnectionsElement *node)
216
{
217
    // FIXME revise
218
}
219
220
void NEDCrossValidator::checkGate(GateElement *gate, bool hasGateIndex, bool isInput, NEDElement *conn, bool isSrc)
221
{
222
    // FIXME revise
223
    // check gate direction, check if vector
224
    const char *q = isSrc ? "wrong source gate for connection" : "wrong destination gate for connection";
225
    if (hasGateIndex && !gate->getIsVector())
226
        errors->addError(conn, "%s: extra gate index or '++' ('%s' is not a vector gate)", q, gate->getName());
227
    else if (!hasGateIndex && gate->getIsVector())
228
        errors->addError(conn, "%s: missing gate index ('%s' is a vector gate)", q, gate->getName());
229
230
    // check gate direction, check if vector
231
    if (isInput && gate->getType()==NED_GATETYPE_OUTPUT)
232
        errors->addError(conn, "%s: input gate expected but '%s' is an output gate", q, gate->getName());
233
    else if (!isInput && gate->getType()==NED_GATETYPE_INPUT)
234
        errors->addError(conn, "%s: output gate expected but '%s' is an input gate", q, gate->getName());
235
}
236
237
void NEDCrossValidator::validateConnGate(const char *submodName, bool hasSubmodIndex,
238
                                            const char *gateName, bool hasGateIndex,
239
                                            NEDElement *parent, NEDElement *conn, bool isSrc)
240
{
241
    // FIXME revise
242
    const char *q = isSrc ? "wrong source gate for connection" : "wrong destination gate for connection";
243
    if (opp_isempty(submodName))
244
    {
245
        // connected to parent module: check such gate is declared
246
        NEDElement *gates = parent->getFirstChildWithTag(NED_GATES);
247
        GateElement *gate;
248
        if (!gates || (gate=(GateElement*)gates->getFirstChildWithAttribute(NED_GATE, "name", gateName))==NULL)
249
            errors->addError(conn, "%s: compound module has no gate named '%s'", q, gateName);
250
        else
251
            checkGate(gate, hasGateIndex, isSrc, conn, isSrc);
252
    }
253
    else
254
    {
255
        // check such submodule is declared
256
        NEDElement *submods = parent->getFirstChildWithTag(NED_SUBMODULES);
257
        SubmoduleElement *submod = NULL;
258
        if (!submods || (submod=(SubmoduleElement*)submods->getFirstChildWithAttribute(NED_SUBMODULE, "name", submodName))==NULL)
259
        {
260
            errors->addError(conn, "%s: compound module has no submodule named '%s'", q, submodName);
261
        }
262
        else
263
        {
264
            bool isSubmodVector = submod->getFirstChildWithAttribute(NED_EXPRESSION, "target", "vector-size")!=NULL;
265
            if (hasSubmodIndex && !isSubmodVector)
266
                errors->addError(conn, "%s: extra submodule index ('%s' is not a vector submodule)", q, submodName);
267
            else if (!hasSubmodIndex && isSubmodVector)
268
                errors->addError(conn, "%s: missing submodule index ('%s' is a vector submodule)", q, submodName);
269
270
            // check gate
271
            NEDElement *submodType = getModuleDeclaration(submod->getType());
272
            if (!submodType)
273
                return; // we gave error earlier if submod type is not present
274
            NEDElement *gates = submodType->getFirstChildWithTag(NED_GATES);
275
            GateElement *gate;
276
            if (!gates || (gate=(GateElement*)gates->getFirstChildWithAttribute(NED_GATE, "name", gateName))==NULL)
277
                errors->addError(conn, "%s: submodule '%s' has no gate named '%s'", q, submodName, gateName);
278
            else
279
                checkGate(gate, hasGateIndex, !isSrc, conn, isSrc);
280
        }
281
    }
282
}
283
284
void NEDCrossValidator::validateElement(ConnectionElement *node)
285
{
286
    // FIXME revise
287
    // make sure submodule and gate names are valid, gate direction is OK
288
    // and that gates & modules are really vector (or really not)
289
    NEDElement *compound = node->getParentWithTag(NED_COMPOUND_MODULE);
290
    if (!compound)
291
        INTERNAL_ERROR0(node,"occurs outside a compound-module");
292
293
    bool srcModIx =   node->getFirstChildWithAttribute(NED_EXPRESSION, "target", "src-module-index")!=NULL;
294
    bool srcGateIx =  node->getFirstChildWithAttribute(NED_EXPRESSION, "target", "src-gate-index")!=NULL || node->getSrcGatePlusplus();
295
    bool destModIx =  node->getFirstChildWithAttribute(NED_EXPRESSION, "target", "dest-module-index")!=NULL;
296
    bool destGateIx = node->getFirstChildWithAttribute(NED_EXPRESSION, "target", "dest-gate-index")!=NULL || node->getDestGatePlusplus();
297
    validateConnGate(node->getSrcModule(), srcModIx, node->getSrcGate(), srcGateIx, compound, node, true);
298
    validateConnGate(node->getDestModule(), destModIx, node->getDestGate(), destGateIx, compound, node, false);
299
}
300
301
void NEDCrossValidator::validateElement(ChannelSpecElement *node)
302
{
303
    // FIXME revise
304
}
305
306
void NEDCrossValidator::validateElement(ChannelInterfaceElement *node)
307
{
308
    // FIXME revise
309
}
310
311
void NEDCrossValidator::validateElement(ChannelElement *node)
312
{
313
    // FIXME revise
314
    // make sure channel type name does not exist yet
315
    if (getChannelDeclaration(node->getName()))
316
        errors->addError(node, "redefinition of channel with name '%s'",node->getName());
317
}
318
319
void NEDCrossValidator::validateElement(ConnectionGroupElement *node)
320
{
321
    // FIXME revise
322
}
323
324
void NEDCrossValidator::validateElement(LoopElement *node)
325
{
326
    // FIXME revise
327
}
328
329
void NEDCrossValidator::validateElement(ConditionElement *node)
330
{
331
    // FIXME revise
332
}
333
334
void NEDCrossValidator::validateElement(ExpressionElement *node)
335
{
336
    // FIXME revise
337
}
338
339
void NEDCrossValidator::validateElement(OperatorElement *node)
340
{
341
    // FIXME revise
342
}
343
344
void NEDCrossValidator::validateElement(FunctionElement *node)
345
{
346
    // FIXME revise
347
}
348
349
void NEDCrossValidator::validateElement(IdentElement *node)
350
{
351
    // FIXME revise
352
}
353
354
void NEDCrossValidator::validateElement(LiteralElement *node)
355
{
356
}
357
358
void NEDCrossValidator::validateElement(MsgFileElement *node)
359
{
360
}
361
362
void NEDCrossValidator::validateElement(NamespaceElement *node)
363
{
364
}
365
366
void NEDCrossValidator::validateElement(CplusplusElement *node)
367
{
368
}
369
370
void NEDCrossValidator::validateElement(StructDeclElement *node)
371
{
372
}
373
374
void NEDCrossValidator::validateElement(ClassDeclElement *node)
375
{
376
}
377
378
void NEDCrossValidator::validateElement(MessageDeclElement *node)
379
{
380
}
381
382
void NEDCrossValidator::validateElement(PacketDeclElement *node)
383
{
384
}
385
386
void NEDCrossValidator::validateElement(EnumDeclElement *node)
387
{
388
}
389
390
void NEDCrossValidator::validateElement(EnumElement *node)
391
{
392
    // check extends-name
393
    const char *baseName = node->getExtendsName();
394
    NEDElement *base = getEnumDeclaration(baseName);
395
    if (!base)
396
        errors->addError(node, "unknown base enum type '%s'",baseName);
397
}
398
399
void NEDCrossValidator::validateElement(EnumFieldsElement *node)
400
{
401
}
402
403
void NEDCrossValidator::validateElement(EnumFieldElement *node)
404
{
405
}
406
407
void NEDCrossValidator::validateElement(MessageElement *node)
408
{
409
    // check extends-name
410
    const char *baseClassName = node->getExtendsName();
411
    NEDElement *baseClass = getClassDeclaration(baseClassName);
412
    if (!baseClass)
413
        errors->addError(node, "unknown base class '%s'",baseClassName);
414
}
415
416
void NEDCrossValidator::validateElement(PacketElement *node)
417
{
418
    // check extends-name
419
    const char *baseClassName = node->getExtendsName();
420
    NEDElement *baseClass = getClassDeclaration(baseClassName);
421
    if (!baseClass)
422
        errors->addError(node, "unknown base class '%s'",baseClassName);
423
}
424
425
void NEDCrossValidator::validateElement(ClassElement *node)
426
{
427
    // check extends-name
428
    const char *baseClassName = node->getExtendsName();
429
    NEDElement *baseClass = getClassDeclaration(baseClassName);
430
    if (!baseClass)
431
        errors->addError(node, "unknown base class '%s'",baseClassName);
432
}
433
434
void NEDCrossValidator::validateElement(StructElement *node)
435
{
436
    // check extends-name
437
    const char *baseClassName = node->getExtendsName();
438
    NEDElement *baseClass = getClassDeclaration(baseClassName);
439
    if (!baseClass)
440
        errors->addError(node, "unknown base class '%s'",baseClassName);
441
}
442
443
void NEDCrossValidator::validateElement(FieldElement *node)
444
{
445
}
446
447
void NEDCrossValidator::validateElement(UnknownElement *node)
448
{
449
}