Statistics
| Branch: | Revision:

root / src / eventlog / eventlogentries.pl @ e1750c09

History | View | Annotate | Download (12.6 KB)

1
#
2
# Generates eventlogentry classes from a textual description.
3
#
4
# Author: Levente Meszaros, 2006
5
#
6

    
7
# FIXME parsing: choose different strategy,
8
# current code cannot detect unrecognized field names in the trace file!
9

    
10
$verbose = 0;
11

    
12
open(FILE, "eventlogentries.txt");
13

    
14

    
15
#
16
# Read input file
17
#
18
while (<FILE>)
19
{
20
   chomp;
21
   s/\r$//; # cygwin/mingw perl does not do CR/LF translation
22

    
23
   if ($_ =~ /^ *$/)
24
   {
25
      # blank line
26
   }
27
   elsif ($_ =~ /^ *\/\//)
28
   {
29
      # comment
30
   }
31
   elsif ($_ =~ /^([\w]+) +([\w]+) *(\/\/.*)?$/)
32
   {
33
      $classCode = $1;
34
      $className = $2;
35
      $classComment = $4;
36
      $classHasOptField = 0;
37
      print "$classCode $className\n" if ($verbose);
38
      foreach $class (@classes)
39
      {
40
         if ($classCode eq $class->{CODE})
41
         {
42
            die "Class code $classCode used twice";
43
         }
44
      }
45
   }
46
   elsif ($_ =~ /^ *{ *$/)
47
   {
48
      print "{\n" if ($verbose);
49
   }
50
   elsif ($_ =~ /^ +([\w#]+) +([\w]+) +([\w]+)( +([^ ]+))? *(\/\/.*)?$/)
51
   {
52
      $fieldCode = $1;
53
      $fieldType = $2;
54
      $fieldName = $3;
55
      print "$fieldCode $fieldType $fieldName" if ($verbose);
56

    
57
      if ($fieldType eq "string")
58
      {
59
         $fieldPrintfType = "%s";
60
         $fieldDefault = "NULL";
61
      }
62
      elsif ($fieldType eq "bool")
63
      {
64
         $fieldPrintfType = "%d";
65
         $fieldDefault = "false";
66
      }
67
      elsif ($fieldType eq "int")
68
      {
69
         $fieldPrintfType = "%d";
70
         $fieldDefault = "-1";
71
      }
72
      elsif ($fieldType eq "short")
73
      {
74
         $fieldPrintfType = "%d";
75
         $fieldDefault = "-1";
76
      }
77
      elsif ($fieldType eq "long")
78
      {
79
         $fieldPrintfType = "%ld";
80
         $fieldDefault = "-1";
81
      }
82
      elsif ($fieldType eq "int64")
83
      {
84
         $fieldPrintfType = "%\"INT64_PRINTF_FORMAT\"d";
85
         $fieldDefault = "-1";
86
      }
87
      elsif ($fieldType eq "eventnumber_t")
88
      {
89
         $fieldPrintfType = "%\"EVENTNUMBER_PRINTF_FORMAT\"d";
90
         $fieldDefault = "-1";
91
      }
92
      elsif ($fieldType eq "simtime_t")
93
      {
94
         $fieldPrintfType = "%s";
95
         $fieldDefault = "simtime_nil";
96
      }
97

    
98
      if ($5 ne "") {
99
         $classHasOptField = 1;
100
         $fieldDefault  = $5;
101
         $mandatory = 0;
102
      }
103
      else {
104
         $mandatory = 1;
105
      }
106

    
107
      $comment = $7;
108

    
109
      $fieldCType = $fieldType;
110
      $fieldCType =~ s/string/const char */;
111
      $field = {
112
         CODE => $fieldCode,
113
         TYPE => $fieldType,
114
         CTYPE => $fieldCType,
115
         PRINTFTYPE => $fieldPrintfType,
116
         NAME => $fieldName,
117
         MANDATORY => $mandatory,
118
         DEFAULTVALUE => $fieldDefault,
119
         COMMENT => $comment,
120
      };
121

    
122
      push(@fields, $field);
123
      print " $fieldCode $fieldType $fieldName $fieldDefault\n" if ($verbose);
124
   }
125
   elsif ($_ =~ /^ *} *$/)
126
   {
127
      $class = {
128
         CODE => $classCode,
129
         NAME => $className,
130
         HASOPT => $classHasOptField,
131
         FIELDS => [ @fields ],
132
         COMMENT => $classComment,
133
      };
134
      push(@classes, $class);
135
      @fields = ();
136
      print "}\n" if ($verbose);
137
   }
138
   else
139
   {
140
       die "unrecognized line \"$_\"";
141
   }
142
}
143

    
144
close(FILE);
145

    
146

    
147

    
148
#
149
# Write eventlogentries header file
150
#
151

    
152
open(ENTRIES_H_FILE, ">eventlogentries.h");
153

    
154
print ENTRIES_H_FILE
155
"//=========================================================================
156
//  EVENTLOGENTRIES.H - part of
157
//                  OMNeT++/OMNEST
158
//           Discrete System Simulation in C++
159
//
160
//  This is a generated file -- do not modify.
161
//
162
//=========================================================================
163

    
164
#ifndef __EVENTLOGENTRIES_H_
165
#define __EVENTLOGENTRIES_H_
166

    
167
#include <stdio.h>
168
#include \"eventlogdefs.h\"
169
#include \"eventlogentry.h\"
170

    
171
NAMESPACE_BEGIN
172

    
173
class Event;
174

    
175
";
176

    
177
$index = 1;
178

    
179
foreach $class (@classes)
180
{
181
   print ENTRIES_H_FILE "
182
class EVENTLOG_API $class->{NAME} : public EventLogTokenBasedEntry
183
{
184
   public:
185
      $class->{NAME}();
186
      $class->{NAME}(Event *event, int entryIndex);
187

    
188
   public:";
189
   foreach $field (@{ $class->{FIELDS} })
190
   {
191
      print ENTRIES_H_FILE "
192
      $field->{CTYPE} $field->{NAME};";
193
   }
194
   print ENTRIES_H_FILE "
195

    
196
   public:
197
      virtual void parse(char **tokens, int numTokens);
198
      virtual void print(FILE *file);
199
      virtual int getClassIndex() { return $index; }
200
      virtual const char *getDefaultAttribute() const { return \"$class->{CODE}\"; }
201
      virtual const std::vector<const char *> getAttributeNames() const;
202
      virtual const char *getAttribute(const char *name) const; // BEWARE: Returns pointer into a static buffer which gets overwritten with each call!
203
      virtual const char *getClassName() { return \"$class->{NAME}\"; }
204
};
205
";
206

    
207
   $index++;
208
}
209

    
210
print ENTRIES_H_FILE "
211
NAMESPACE_END
212

    
213
#endif
214
";
215

    
216
close(ENTRIES_H_FILE);
217

    
218

    
219

    
220
#
221
# Write eventlogentries.cc file
222
#
223

    
224
open(ENTRIES_CC_FILE, ">eventlogentries.cc");
225

    
226
print ENTRIES_CC_FILE
227
"//=========================================================================
228
//  EVENTLOGENTRIES.CC - part of
229
//                  OMNeT++/OMNEST
230
//           Discrete System Simulation in C++
231
//
232
//  This is a generated file -- do not modify.
233
//
234
//=========================================================================
235

    
236
#include <stdio.h>
237
#include \"event.h\"
238
#include \"eventlogentries.h\"
239
#include \"stringutil.h\"
240

    
241
USING_NAMESPACE
242

    
243
";
244

    
245
foreach $class (@classes)
246
{
247
   $className = $class->{NAME};
248

    
249
   # constructors
250
   print ENTRIES_CC_FILE "$className\::$className()\n";
251
   print ENTRIES_CC_FILE "{\n";
252
   print ENTRIES_CC_FILE "    this->event = NULL;\n";
253
   foreach $field (@{ $class->{FIELDS} })
254
   {
255
      print ENTRIES_CC_FILE "    $field->{NAME} = $field->{DEFAULTVALUE};\n";
256
   }
257
   print ENTRIES_CC_FILE "}\n\n";
258

    
259
   print ENTRIES_CC_FILE "$className\::$className(Event *event, int entryIndex)\n";
260
   print ENTRIES_CC_FILE "{\n";
261
   print ENTRIES_CC_FILE "    this->event = event;\n";
262
   print ENTRIES_CC_FILE "    this->entryIndex = entryIndex;\n";
263
   foreach $field (@{ $class->{FIELDS} })
264
   {
265
      print ENTRIES_CC_FILE "    $field->{NAME} = $field->{DEFAULTVALUE};\n";
266
   }
267
   print ENTRIES_CC_FILE "}\n\n";
268

    
269
   # parse
270
   print ENTRIES_CC_FILE "void $className\::parse(char **tokens, int numTokens)\n";
271
   print ENTRIES_CC_FILE "{\n";
272
   foreach $field (@{ $class->{FIELDS} })
273
   {
274
      if ($field->{TYPE} eq "int")
275
      {
276
        $parserFunction = "getIntToken";
277
      }
278
      elsif ($field->{TYPE} eq "short")
279
      {
280
        $parserFunction = "getShortToken";
281
      }
282
      elsif ($field->{TYPE} eq "long")
283
      {
284
        $parserFunction = "getLongToken";
285
      }
286
      elsif ($field->{TYPE} eq "int64")
287
      {
288
        $parserFunction = "getInt64Token";
289
      }
290
      elsif ($field->{TYPE} eq "string")
291
      {
292
        $parserFunction = "getStringToken";
293
      }
294
      elsif ($field->{TYPE} eq "eventnumber_t")
295
      {
296
        $parserFunction = "getEventNumberToken";
297
      }
298
      elsif ($field->{TYPE} eq "simtime_t")
299
      {
300
        $parserFunction = "getSimtimeToken";
301
      }
302
      elsif ($field->{TYPE} eq "bool")
303
      {
304
        $parserFunction = "getBoolToken";
305
      }
306
      else
307
      {
308
         die "Unknown type: $field->{TYPE}";
309
      }
310
      if ($field->{MANDATORY})
311
      {
312
         $mandatory = "true";
313
      }
314
      else
315
      {
316
         $mandatory = "false";
317
      }
318
      print ENTRIES_CC_FILE "    $field->{NAME} = $parserFunction(tokens, numTokens, \"$field->{CODE}\", $mandatory, $field->{NAME});\n";
319
   }
320
   print ENTRIES_CC_FILE "}\n\n";
321

    
322
   # print
323
   print ENTRIES_CC_FILE "void $className\::print(FILE *fout)\n";
324
   print ENTRIES_CC_FILE "{\n";
325
   if ($class->{NAME} eq "EventEntry")
326
   {
327
      print ENTRIES_CC_FILE "    fprintf(fout, \"\\n\");\n";
328
   }
329
   print ENTRIES_CC_FILE "    fprintf(fout, \"$class->{CODE}\");\n";
330

    
331
   foreach $field (@{ $class->{FIELDS} })
332
   {
333
      if ($field->{TYPE} eq "string")
334
      {
335
         if ($field->{MANDATORY} eq 0)
336
         {
337
            print ENTRIES_CC_FILE "    if ($field->{NAME})\n    ";
338
         }
339
         print ENTRIES_CC_FILE "    fprintf(fout, \" $field->{CODE} $field->{PRINTFTYPE}\", QUOTE($field->{NAME}));\n";
340
      }
341
      elsif ($field->{TYPE} eq "simtime_t")
342
      {
343
         if ($field->{MANDATORY} eq 0)
344
         {
345
            print ENTRIES_CC_FILE "    if ($field->{NAME} != $field->{DEFAULTVALUE})\n    ";
346
         }
347
         print ENTRIES_CC_FILE "    fprintf(fout, \" $field->{CODE} $field->{PRINTFTYPE}\", $field->{NAME}.str(buffer));\n";
348
      }
349
      else
350
      {
351
         if ($field->{MANDATORY} eq 0)
352
         {
353
            print ENTRIES_CC_FILE "    if ($field->{NAME} != $field->{DEFAULTVALUE})\n    ";
354
         }
355
         print ENTRIES_CC_FILE "    fprintf(fout, \" $field->{CODE} $field->{PRINTFTYPE}\", $field->{NAME});\n";
356
      }
357
   }
358

    
359
   print ENTRIES_CC_FILE "    fprintf(fout, \"\\n\");\n";
360
   print ENTRIES_CC_FILE "    fflush(fout);\n";
361
   print ENTRIES_CC_FILE "}\n\n";
362

    
363

    
364
   # getAttributeNames
365
   print ENTRIES_CC_FILE "const std::vector<const char *> $className\::getAttributeNames() const\n";
366
   print ENTRIES_CC_FILE "{\n";
367
   print ENTRIES_CC_FILE "    std::vector<const char *> names;\n";
368
   foreach $field (@{ $class->{FIELDS} })
369
   {
370
      print ENTRIES_CC_FILE "    names.push_back(\"$field->{CODE}\");\n";
371
   }
372
   print ENTRIES_CC_FILE "    return names;\n";
373
   print ENTRIES_CC_FILE "}\n\n";
374

    
375
   # getAttribute
376
   print ENTRIES_CC_FILE "const char *$className\::getAttribute(const char *name) const\n";
377
   print ENTRIES_CC_FILE "{\n";
378
   print ENTRIES_CC_FILE "    if (false);\n";
379

    
380
   foreach $field (@{ $class->{FIELDS} })
381
   {
382
      print ENTRIES_CC_FILE "    else if (!strcmp(name, \"$field->{CODE}\"))\n";
383
      if ($field->{TYPE} eq "string")
384
      {
385
         print ENTRIES_CC_FILE "        return $field->{NAME};\n";
386
      }
387
      elsif ($field->{TYPE} eq "simtime_t")
388
      {
389
         print ENTRIES_CC_FILE "        return $field->{NAME}.str(buffer);\n";
390
      }
391
      else
392
      {
393
         print ENTRIES_CC_FILE "    {\n";
394
         print ENTRIES_CC_FILE "        sprintf(buffer, \"$field->{PRINTFTYPE}\", $field->{NAME});\n";
395
         print ENTRIES_CC_FILE "        return buffer;\n";
396
         print ENTRIES_CC_FILE "    }\n";
397
      }
398
   }
399

    
400
   print ENTRIES_CC_FILE "    else\n";
401
   print ENTRIES_CC_FILE "        return NULL;\n";
402
   print ENTRIES_CC_FILE "}\n\n";
403
}
404

    
405
close(ENTRIES_CC_FILE);
406

    
407

    
408

    
409
#
410
# Write eventlogentryfactory cc file
411
#
412

    
413
open(FACTORY_CC_FILE, ">eventlogentryfactory.cc");
414

    
415
print FACTORY_CC_FILE
416
"//=========================================================================
417
//  EVENTLOGENTRYFACTORY.CC - part of
418
//                  OMNeT++/OMNEST
419
//           Discrete System Simulation in C++
420
//
421
//  This is a generated file -- do not modify.
422
//
423
//=========================================================================
424

    
425
#include <stdio.h>
426
#include \"event.h\"
427
#include \"eventlogentryfactory.h\"
428

    
429
USING_NAMESPACE
430

    
431
EventLogTokenBasedEntry *EventLogEntryFactory::parseEntry(Event *event, int entryIndex, char **tokens, int numTokens)
432
{
433
    if (numTokens < 1)
434
        return NULL;
435

    
436
    char *code = tokens[0];
437
    EventLogTokenBasedEntry *entry;
438

    
439
    if (false)
440
        ;
441
";
442

    
443
foreach $class (@classes)
444
{
445
   #print FACTORY_CC_FILE "    else if (!strcmp(code, \"$class->{CODE}\"))\n";
446
   print FACTORY_CC_FILE "    else if (";
447
   $i=0;
448
   foreach $c (split(//, $class->{CODE})) {
449
       print FACTORY_CC_FILE "code\[$i\]=='$c' && ";
450
       $i++;
451
   }
452
   print FACTORY_CC_FILE "code[$i]==0)  // $class->{CODE}\n";
453

    
454
   print FACTORY_CC_FILE "        entry = new $class->{NAME}(event, entryIndex);\n";
455
}
456
print FACTORY_CC_FILE "    else\n";
457
print FACTORY_CC_FILE "        return NULL;\n\n";
458
print FACTORY_CC_FILE "    entry->parse(tokens, numTokens);\n";
459
print FACTORY_CC_FILE "    return entry;\n";
460
print FACTORY_CC_FILE "}\n";
461

    
462
close(FACTORY_CC_FILE);
463

    
464

    
465
#
466
# Write eventlogentries csv file
467
#
468

    
469
open(ENTRIES_CSV_FILE, ">eventlogentries.csv");
470

    
471
print ENTRIES_CSV_FILE "Name\tType\tDescription\n";
472

    
473
foreach $class (@classes)
474
{
475
   print ENTRIES_CSV_FILE "$class->{CODE}\t\t$class->{COMMENT}\n";
476

    
477
   foreach $field (@{ $class->{FIELDS} })
478
   {
479
      if ($field->{TYPE} eq "bool")
480
      {
481
         print ENTRIES_CSV_FILE "$field->{CODE}\tboolean\t$field->{COMMENT}\n";
482
      }
483
      elsif (($field->{TYPE} eq "int") || $field->{TYPE} eq "long")
484
      {
485
         print ENTRIES_CSV_FILE "$field->{CODE}\tinteger\t$field->{COMMENT}\n";
486
      }
487
      elsif ($field->{TYPE} eq "eventnumber_t")
488
      {
489
         print ENTRIES_CSV_FILE "$field->{CODE}\tevent number\t$field->{COMMENT}\n";
490
      }
491
      elsif ($field->{TYPE} eq "simtime_t")
492
      {
493
         print ENTRIES_CSV_FILE "$field->{CODE}\tsimulation time\t$field->{COMMENT}\n";
494
      }
495
      else
496
      {
497
         print ENTRIES_CSV_FILE "$field->{CODE}\t$field->{TYPE}\t$field->{COMMENT}\n";
498
      }
499
   }
500
}
501

    
502
close(ENTRIES_CSV_FILE);