modules.cc 20 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
2
3
4
/*
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.

Uwe Schulzweida's avatar
Uwe Schulzweida committed
5
  Copyright (C) 2003-2020 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6
7
8
9
10
11
12
13
14
15
16
17
  See COPYING file for copying and redistribution conditions.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
*/

18
#include "modules.h"
19
#include "util_string.h"
20
#include "cdo_output.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
21

22
#include <cstring>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
23
#include <algorithm>  // for std::sort()
24
25

/* removes '-' from operator string and returns copy of parameter operatorCommand */
Oliver Heidmann's avatar
Oliver Heidmann committed
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/***
  vector for library handles for loaded custom modules
  */
std::vector<void *> custom_modules_lib_handles;

/***
  Maps operator names to their module names
 */
std::map<std::string, std::string> modules_map;

/***
  Contains added modules as values and their names as key
  */
std::map<std::string, module_t> modules;

/***
  Key: operator alias / Value: operator original name
 */
std::map<std::string, std::string> aliases;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
45

46
static const char *
47
48
getOperatorName(const char *operatorCommand)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
  char *operatorName = nullptr;
50
51
52
53
54

  if (operatorCommand)
    {
      if (operatorCommand[0] == '-') operatorCommand++;
      const char *commapos = strchr(operatorCommand, ',');
55
      const auto len = (commapos != nullptr) ? (size_t)(commapos - operatorCommand) : strlen(operatorCommand);
56
57
58

      operatorName = (char *) malloc(len + 1);

59
60
61
62
      if (operatorName != nullptr)
        {
          memcpy(operatorName, operatorCommand, len);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63
64
65
66
      else
        {
          return nullptr;
        }
67
68
69
70
71
72
      operatorName[len] = '\0';
    }

  return operatorName;
}

73
74
75
76
77
78
79
80
/**
 * @param a pointer to a string/substring
 * @param b pointer to a string/substring
 * @param alen length of string a
 * @param blen lenght of string b
 * @retval true if a is similar to b
 * @retval false if a is not similar to b
 *
81
 * Recursive function for finding substrings of a operator name that match other operators.
82
 */
83
84
85
86
static bool
similar(const char *a, const char *b, unsigned long alen, unsigned long blen)
{
  if (alen > 2 && blen > 2 && strstr(b, a)) return true;
87

88
89
90
91
  while (*a && *b && *a == *b)
    {
      a++;
      b++;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
92
    }
93
  if (!*a && !*b) return true;
94
95
96

  //  printf("%d %d %s %s\n", alen, blen, a, b);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
97
  if (alen >= 2 && blen >= 1 && *a && similar(a + 1, b, alen - 2, blen - 1)) return true;
98

Uwe Schulzweida's avatar
Uwe Schulzweida committed
99
  if (alen >= 1 && blen >= 2 && *b && similar(a, b + 1, alen - 1, blen - 2)) return true;
100

101
  return false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
102
103
}

104
105
106
107
108
109
110
111
/**
 * @param original string tested for similarity to \p other
 * @param other string that \p original will be compared to
 * @retval true if original and other are similar
 * @retval false if not
 *
 * Wrapper function for #similar() to parse c++ strings to c strings
 */
112
113
114
static bool
similar(std::string original, std::string other)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
115
  return (similar(original.c_str(), other.c_str(), original.size(), other.size()));
116
}
117

118
119
120
121
122
/**
 * @param operatorName operator name
 * @retval true if #modules_map contains \p operatorName
 * @retval false if not
 */
123
static bool
124
operator_name_exists(const std::string &operatorName)
125
{
126
127
128
129
  if (modules_map.find(operatorName) != modules_map.end()) return true;

  if (aliases.find(operatorName) != aliases.end()) return true;

130
  return false;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
131
132
}

133
134
135
136
137
/**
 * @param moduleName module name
 * @retval true if #modules contains \a moduleName
 * @retval false if not
 */
138
/*
139
140
141
142
143
144
145
146
147
static bool
module_map_contains(std::string moduleName)
{
  if (modules.find(moduleName) != modules.end())
    {
      return true;
    }
  else
    {
148
      cdoAbort("Module %s not found", moduleName.c_str());
149
150
    }
  return false;
151
}
152
*/
153
154
155
156
157
158
/***
 * function for finding similar operator names for the given string
 * @param operatorName operator name to find similar operators for
 * @returns A string with all found names. The string is seqmented into lines
 * with a max lenght of 75 characters
 */
159
static std::string
160
find_similar(const std::string &operatorName)
161
162
{
  std::string found_similar_operators = "";
163
164
  size_t lines = 1;
  constexpr size_t line_length = 105;
165

166
167
  if (operatorName != "")
    {
168
      // Searching for similar operator names in operator to module map
169
      for (const auto &str : modules_map)
170
        {
171
          if (similar(stringToLower(operatorName), str.first))
172
            {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
173
              if (found_similar_operators.size() + str.first.size() > lines * line_length)
174
175
176
                {
                  found_similar_operators += "\n";
                  lines++;
177
                }
178
179
              found_similar_operators += str.first;
              found_similar_operators += " ";
180
181
            }
        }
182
      // Searching for similar operator names in aliases to original map
183
      for (const auto &str : aliases)
184
        {
185
          if (similar(stringToLower(operatorName), str.first))
186
            {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
187
              if (found_similar_operators.size() + str.first.size() > lines * line_length)
188
189
190
                {
                  found_similar_operators += "\n";
                  lines++;
191
                }
192
193
              found_similar_operators += str.first;
              found_similar_operators += " ";
194
195
196
            }
        }
    }
197

198
  return found_similar_operators;
199
}
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214
/**
 * @param operatorName operator name.
 * @retval true if \p operatorName exists.
 * @retval false if \p operatorName is not in #modules_map
 *
 * Checks if given \p operatorName is in #modules_map. Else returns false.

 * Checks if \p operatorName is not a file.

 * If no matching operator is found checks for similar operators using
 find_similar().
 *
 *  \note If \p operatorName is a file name the program will exit.
 */
215
static bool
216
check_operator(const std::string &operatorName)
217
218
219
220
221
222
{
  if (operator_name_exists(operatorName))
    {
      return true;
    }
  else if (operatorName == "")
Uwe Schulzweida's avatar
Uwe Schulzweida committed
223
    {
224
      cdoAbort("Operator name missing!");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
225
    }
226
227
228
  else
    {
      // Checking if the operatorname is an existing file name
Uwe Schulzweida's avatar
Uwe Schulzweida committed
229
      auto fp = fopen(operatorName.c_str(), "r");
230
231
232
      if (fp)
        {
          fclose(fp);
233
          fprintf(stderr, "Use commandline option -h for help.\n");
234
          cdoAbort("Operator missing, %s is a file on disk!", operatorName.c_str());
235
        }
236
237
238
239
      // Operator is no filename
      // Checking for similar operators
      fprintf(stderr, "Operator >%s< not found!\n", operatorName.c_str());
      fprintf(stderr, "Similar operators are:\n");
240
      const auto found_similar_operators = find_similar(operatorName);
241

242
243
      if (found_similar_operators.size() > 0)
        {
244
          std::cerr << found_similar_operators << std::endl;
245
246
247
        }
      else
        {
248
249
          fprintf(stderr, "(not found)\n");
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
250

251
      exit(EXIT_FAILURE);
252
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
253

254
  return false;
255
}
256

Oliver Heidmann's avatar
Oliver Heidmann committed
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
void
registerOperatorsFromModules()
{
  for (auto &x : modules)
    {
      for (auto y : x.second.operators)
        {
          if (!operator_name_exists(y))
            {
              modules_map[y] = x.first;
            }
          else
            {
              cdoAbort("Tried to add operator but the operator name already exists");
            }
        }
    }
}

276
277
278
279
280
281
282
/***
 * Adds a module and its operators to cdo.
 * Adds the module to modules
 * Adds the operators of modules to modules_map
 * @param new_module newly constructed module
 * @note: if an error happens while adding the new module cdo will exit.
 */
283
void
Uwe Schulzweida's avatar
Uwe Schulzweida committed
284
add_module(const std::string &module_name, const module_t &new_module)
285
286
287
288
{
  if (modules.find(module_name) == modules.end())
    {
      modules[module_name] = new_module;
289
      for (const auto &operatorName : new_module.operators)
290
291
292
293
294
295
296
297
        {
          // if the operator name is not already in the map or in the aliases
          if (!operator_name_exists(operatorName))
            {
              modules_map[operatorName] = module_name;
            }
          else
            {
298
              cdoAbort("Tried to add operator but the operator name already exists");
299
300
            }
        }
301
302
303
    }
  else
    {
304
      cdoAbort("Module %s name already exists", module_name.c_str());
305
306
    }
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
307

308
/**
309
 * adds an key value pair to #modules_map with alias as key and originals name as value
310
311
312
 * @param alias new alias to be added
 * @param original original operator name
 */
313
int
314
add_alias(const std::string &alias, const std::string &original)
315
316
317
{
  auto iter_original = modules_map.find(original);
  auto iter_alias = aliases.find(alias);
318

319
320
  if (iter_alias != aliases.end())
    {
321
      printf("WARNING: alias %s could not be added: it already exists\n", alias.c_str());
322
      return -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
323
324
    }

325
326
  if (iter_original == modules_map.end())
    {
327
      printf("ERROR: alias %s could not be added: operator %s does not exist\n", alias.c_str(), original.c_str());
328
      return -2;
329
    }
330

331
332
  if (modules_map.find(alias) != modules_map.end())
    {
333
      printf("ERROR alias %s could not be added: alias name already exists as an operator\n", alias.c_str());
334
      return -3;
335
    }
336

337
  aliases[alias] = original;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
338

339
  return 0;
340
341
342
343
344
345
346
347
348
349
}

/***
 * returns the module of given operator
 *
 * parameters:
 *      std::string operatorName -> name of the operator
 * return value:
 *      std::string -> name of the operators module
 */
350
static std::string
351
get_module_name_to(const std::string &operatorName)
352
353
354
355
356
357
358
359
360
361
362
{
  // if not true the programm will exit in function check_operator
  if (check_operator(operatorName))
    {
      if (modules_map.count(operatorName) > 0)
        {
          return modules_map[operatorName];
        }
      else if (aliases.count(operatorName) > 0)
        {
          return modules_map[aliases[operatorName]];
363
364
        }
    }
365
366
367
368
  else
    {
      // TODO: see if depricated since no operator can be added without a
      // module
369
      cdoAbort("Module for >%s< not installed", operatorName.c_str());
370
371
372
    }
  // Only to quell the warning. Function should never reach this.
  return "";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373
374
}

375
376
377
378
379
/**
 * @fn void *(*operatorModule(const char *operatorName))(void *)

 * returns the function of the module of \a operatorName
 * @param operatorName name of the operator
380
 * @returns the function of the #module_t of \a operatorName
381
 */
382
/* not used
383
384
385
386
void *(*operatorModule(const char *operatorName))(void *)
{
  std::string operator_name = std::string(operatorName);
  return modules[get_module_name_to(operator_name)].func;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
387
}
388
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
389

390
391
/***
 * returns help for given operator name
392
 * if there is no help nullptr will be returned
393
394
395
 * @param operatorName operator name
 * @return vector of strings containing the help
 */
396
const char **
397
operatorHelp(const std::string &operatorName)
398
{
399
  return modules[get_module_name_to(operatorName)].help;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
400
401
}

402
/***
403
404
405
406
407
 * Returns the number of input streams a operator takes.
 * returns -1 for a unlimited number of input streams.
 * @param operatorName operator name
 * @retval short
 */
408
/* not used
409
410
411
412
413
int
operatorStreamInCnt(const char *operatorName)
{
  std::string operator_name = std::string(operatorName);
  return modules[get_module_name_to(operator_name)].streamInCnt;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
414
}
415
*/
416
417
418
419
420
421
422
/***
 * Returns the number of output streams a given operator has.
 * returns -1 if obase is used
 * @param operatorName operator name
 * @return 1 for CDI_REAL, 2 for CDI_COMP (complex), 3 for CDI_REAL and CDI_COMP
 * @retval short
 */
423
/* not used
424
425
426
427
428
int
operatorStreamOutCnt(const char *operatorName)
{
  std::string operator_name = std::string(operatorName);
  return modules[get_module_name_to(operator_name)].streamOutCnt;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
429
}
430
*/
431
/***
432
433
434
435
 * Returns the number type this operator works with
 * @param operatorName operator name
 * @reval short
 */
436
437
438
439
440
int
operatorStreamNumber(const char *operatorName)
{
  std::string operator_name = std::string(operatorName);
  return modules[get_module_name_to(operator_name)].number;
441
442
443
}

/***
444
 * Creates a sorted vector with all operator names and alisases excluding all modules that are marked as internal
445
446
 * @return a sorted std::vector containing all operator names and aliases
 * excluding all operators which modules are marked as internal
447
 */
448
449
450
static std::vector<std::string>
get_sorted_operator_name_list()
{
451

452
  std::vector<std::string> names;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
453
  for (const auto &operator_module_names_pair : modules_map)
454
455
456
457
    {
      if (modules[operator_module_names_pair.second].mode == 1)
        {
          names.push_back(operator_module_names_pair.first);
458
459
        }
    }
460
  // adding operators names from alias_map
Uwe Schulzweida's avatar
Uwe Schulzweida committed
461
  for (const auto &alias : aliases)
462
463
    {
      names.push_back(alias.first);
464
    }
465
  std::sort(names.begin(), names.end());
Uwe Schulzweida's avatar
Uwe Schulzweida committed
466

467
  return names;
468
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
469

470
471
std::vector<std::string>
get_no_output_operator_list()
472
{
473
  std::vector<std::string> names;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
474
  for (const auto &operator_module_names_pair : modules_map)
475
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
476
      if (modules[operator_module_names_pair.second].mode == 1 && modules[operator_module_names_pair.second].streamOutCnt == 0)
477
        {
478
          names.push_back(operator_module_names_pair.first);
479
480
        }
    }
481
  // adding operators names from alias_map
Uwe Schulzweida's avatar
Uwe Schulzweida committed
482
  for (const auto &alias : aliases)
483
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
484
      const auto &original = alias.second;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
485
      if (modules[modules_map[original]].mode == 1 && modules[modules_map[original]].streamOutCnt == 0)
486
487
        {
          names.push_back(alias.first);
488
489
        }
    }
490
  std::sort(names.begin(), names.end());
Uwe Schulzweida's avatar
Uwe Schulzweida committed
491

492
  return names;
493
494
}

495
496
497
498
499
500
501
void
operatorPrintAll(void)
{
  int number_of_chars = 0;
  std::string tab = "   ";
  int tab_width = tab.size();
  // using a set because it sorts the operators alphabetically on its own
Uwe Schulzweida's avatar
Uwe Schulzweida committed
502
  std::vector<std::string> sorted_operator_names = get_sorted_operator_name_list();
503
504

  std::cout << tab;
505
  for (const auto &operatorName : sorted_operator_names)
506
507
508
509
510
    {
      if (number_of_chars > 85)
        {
          number_of_chars = tab_width;
          std::cerr << std::endl << tab;
511
512
        }

513
514
      std::cerr << " " << operatorName;
      number_of_chars += 1 + operatorName.size();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
515
    }
516

517
  std::cerr << std::endl;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
518
}
519

520
521
522
523
524
#ifdef CUSTOM_MODULES
/***
  loads all custom modules in a specified folder
  @param folder_path custom modules folder
*/
525
526
527
528
529
530
void
load_custom_modules(std::string folder_path)
{
  DIR *dir = opendir(folder_path.c_str());
  std::string file_path;
  std::regex library_regex("(.*\\.so)");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
531
  if (dir != nullptr)
532
533
    {
      struct dirent *ent = readdir(dir);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
      while (ent != nullptr)
535
536
537
538
539
        {
          if (std::regex_match(ent->d_name, library_regex))
            {
              file_path = folder_path + "/" + ent->d_name;
              load_custom_module(file_path);
540
            }
541
          ent = readdir(dir);
542
        }
543
544
545
    }
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
546
      std::cerr << "Could not find " << folder_path << "for loading custom modules" << std::endl;
547
548
549
550
551
552
553
554
555
    }
}

/***
 * Loads a custom module from given path.
 * Modules must contain a (TODO: rename function) init_custom_module function
 * Program exits if a module could not be loaded.
 * @param module file path
 */
556
557
558
559
560
561
562
563
564
565
void
load_custom_module(std::string file_path)
{
  void (*init_custom_module)();
  void *lib_handle = dlopen(file_path.c_str(), RTLD_LAZY);
  custom_modules_lib_handles.push_back(lib_handle);
  if (!lib_handle)
    {
      std::cerr << "Cannot open library: " << dlerror() << std::endl;
      return;
566
567
    }

568
569
570
  dlerror();
  init_custom_module = (void (*)()) dlsym(lib_handle, "init_custom_module");
  const char *dlsym_error = dlerror();
571

572
573
  if (dlsym_error)
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
574
      std::cerr << "Cannot load symbol 'init_custom_module': " << dlsym_error << std::endl;
575
576
      dlclose(lib_handle);
      return;
577
    }
578

579
580
  init_custom_module();
  std::cout << "loaded custom module from '" << file_path << "'" << std::endl;
581
}
582

583
584
585
/***
  closes the handles for the loaded custum modules
*/
586
587
588
589
590
591
void
close_library_handles()
{
  for (unsigned long i = 0; i < custom_modules_lib_handles.size(); i++)
    {
      dlclose(custom_modules_lib_handles[i]);
592
593
594
    }
}
#endif
595

596
// helper function for setting the spacing in operatorPrintList
597
598
static std::string
get_spacing_for(int p_space, const std::string &str)
599
600
{
  std::string spacing = "";
601
  for (int i = str.size(); i <= p_space; i++) spacing += " ";
602
  return spacing;
603
}
604

605
static std::string
606
get_operator_description(const std::string &p_current_op_name, const char **help)
607
{
608
  std::string description = "";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
609
  unsigned long cur_help_idx = 0;
610
611
612
613
  std::string line;
  unsigned long operator_section = 0;

  // search for operator section
614
615
616
617
  size_t help_size = 0;
  while (help[help_size]) help_size++;
  if (!help_size) return description;
  while (operator_section == 0 && cur_help_idx < help_size - 1)
618
619
620
621
622
    {
      line = help[++cur_help_idx];
      if (line.find("OPERATORS") != std::string::npos)
        {
          operator_section = cur_help_idx;
623
624
        }
    }
625
626
627
628
629
630
  // if no operator section is found
  if (operator_section == 0)
    {
      cur_help_idx = 0;
      line = help[0];
      std::string name_section = help[0];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
631
      bool help_contains_name = false;
632
633
634
635
636
637
638
      // search for the operator name in the description
      while (!line.empty())
        {
          line = help[++cur_help_idx];
          if (line.find(p_current_op_name) != std::string::npos)
            {
              help_contains_name = true;
639
            }
640
          name_section += line;
641
        }
642
643
644
      // if the name was found save description for later use
      if (help_contains_name)
        {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
645
          description = name_section.substr(name_section.find_first_of('-') + 2, name_section.size());
646
        }
647
648
649
    }
  else
    {
650
      line = help[++operator_section];
651
      // search the operator section for current operator line
652
      while (line.find(p_current_op_name + " ") == std::string::npos && !line.empty() && operator_section < help_size - 1)
653
        {
654
          line = help[++operator_section];
655
        }
656
      // if operator line found save description for later use
657
      if (!line.empty() && line.find("    " + p_current_op_name + " ") != std::string::npos)
658
659
        {
          auto op_name_start = line.find_first_not_of(" \t");
660

Uwe Schulzweida's avatar
Uwe Schulzweida committed
661
          description = line.substr(line.find_first_not_of(" \t", op_name_start + p_current_op_name.size()), line.size());
662
663
        }
    }
664

665
  return description;
666
}
667

668
669
670
671
672
673
674
/***
 * Prints all operator names and their short descriptions
 * Aliases are listed and point to their original operator name.
 * If the module is not documented the description is empty
 * If a module has only one operator the short module description is listed
 * If the operator is not documented the description is empty
 */
675
676
677
void
operatorPrintList(bool print_no_output)
{
678
  std::vector<std::string> output_list = print_no_output ? get_no_output_operator_list() : get_sorted_operator_name_list();
679

680
  auto list_length = output_list.size();
681

682
  // help variables
683

684
  for (size_t out_list_idx = 0; out_list_idx < list_length; out_list_idx++)
685
    {
686
      auto &current_op_name = output_list[out_list_idx];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
687
      const auto *current_module = &modules[get_module_name_to(current_op_name)];
688
689
      if (aliases.find(current_op_name) != aliases.end())
        {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
690
          output_list[out_list_idx] += std::string(get_spacing_for(16, current_op_name) + "--> " + aliases[current_op_name]);
691
        }
692
      else if (current_module->help)
693
694
        {
          // add spaceing and saving output line to the output list
695
          auto description = get_operator_description(current_op_name, current_module->help);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
696
          output_list[out_list_idx] += get_spacing_for(16, current_op_name) + description;
697
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
698
      std::string in_out_info
699
          = " (" + std::to_string(current_module->streamInCnt) + "|" + std::to_string(current_module->streamOutCnt) + ")";
Uwe Schulzweida's avatar
Uwe Schulzweida committed
700
      output_list[out_list_idx] += get_spacing_for(90, output_list[out_list_idx]) + in_out_info;
701
    }
702
  // print generated output list
703
  for (const std::string &str : output_list)
704
705
    {
      std::cout << str << std::endl;
706
    }
707
}
708

709
static bool
710
is_alias(const char *operatorName)
711
{
712
  return (aliases.find(std::string(operatorName)) != aliases.end());
713
714
}

715
716
const char *
get_original(const char *operatorName)
717
{
718
719
  const char *name = getOperatorName(operatorName);
  if (is_alias(name))
720
    {
721
      const auto &opName = aliases[std::string(name)];
722
      char *original = (char *) malloc(opName.size() + 1);
723
      strcpy(original, opName.c_str());
724
      return original;
725
    }
726
  return name;
727
}
728

729
730
module_t &
getModule(const std::string &operator_name)
731
{
732
  return modules[get_module_name_to(operator_name)];
733
}