LCOV - code coverage report
Current view: top level - progs - mhdump.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 312 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 9 0

            Line data    Source code
       1              : //
       2              : // mhdump: midas history explorer
       3              : //
       4              : // Author: Konstantin Olchanski, 20-NOV-2007
       5              : //
       6              : // Compile: 
       7              : //   g++ -o mhdump.o -c mhdump.cxx -O2 -g -Wall -Wuninitialized
       8              : //   g++ -o mhdump -g -O2 mhdump.o
       9              : //
      10              : // $Id$
      11              : //
      12              : 
      13              : #undef NDEBUG // midas required assert() to be always enabled
      14              : 
      15              : #include <stdio.h>
      16              : #include <stdlib.h>
      17              : #include <stdint.h>
      18              : #include <string.h>
      19              : #include <assert.h>
      20              : #include <errno.h>
      21              : 
      22              : #include <string>
      23              : #include <map>
      24              : #include <vector>
      25              : #include <ctime>
      26              : 
      27              : ////////////////////////////////////////
      28              : // Definitions extracted from midas.h //
      29              : ////////////////////////////////////////
      30              : 
      31              : #define DWORD uint32_t
      32              : 
      33              : #define NAME_LENGTH            32            /**< length of names, mult.of 8! */
      34              : 
      35              : typedef struct {
      36              :    DWORD record_type;           /* RT_DATA or RT_DEF */
      37              :    DWORD event_id;
      38              :    DWORD time;
      39              :    DWORD def_offset;            /* place of definition */
      40              :    DWORD data_size;             /* data following this header in bytes */
      41              : } HIST_RECORD;
      42              : 
      43              : typedef struct {
      44              :    char name[NAME_LENGTH];             /**< - */
      45              :    DWORD type;                         /**< - */
      46              :    DWORD n_data;                       /**< - */
      47              : } TAG;
      48              : 
      49              : ////////////////////////////////////////
      50              : // Definitions extracted from midas.c //
      51              : ////////////////////////////////////////
      52              : 
      53              : /********************************************************************/
      54              : /* data type sizes */
      55              : int tid_size[] = {
      56              :    0,                           /* tid == 0 not defined                               */
      57              :    1,                           /* TID_BYTE      unsigned byte         0       255    */
      58              :    1,                           /* TID_SBYTE     signed byte         -128      127    */
      59              :    1,                           /* TID_CHAR      single character      0       255    */
      60              :    2,                           /* TID_WORD      two bytes             0      65535   */
      61              :    2,                           /* TID_SHORT     signed word        -32768    32767   */
      62              :    4,                           /* TID_DWORD     four bytes            0      2^32-1  */
      63              :    4,                           /* TID_INT       signed dword        -2^31    2^31-1  */
      64              :    4,                           /* TID_BOOL      four bytes bool       0        1     */
      65              :    4,                           /* TID_FLOAT     4 Byte float format                  */
      66              :    8,                           /* TID_DOUBLE    8 Byte float format                  */
      67              :    1,                           /* TID_BITFIELD  8 Bits Bitfield    00000000 11111111 */
      68              :    0,                           /* TID_STRING    zero terminated string               */
      69              :    0,                           /* TID_ARRAY     variable length array of unkown type */
      70              :    0,                           /* TID_STRUCT    C structure                          */
      71              :    0,                           /* TID_KEY       key in online database               */
      72              :    0,                           /* TID_LINK      link in online database              */
      73              :    8,                           /* TID_INT64     8 bytes int          -2^63   2^63-1  */
      74              :    8                            /* TID_UINT64    8 bytes unsigned int  0      2^64-1  */
      75              : };
      76              : 
      77              : /* data type names */
      78              : const char *tid_name[] = {
      79              :    "NULL",
      80              :    "BYTE",
      81              :    "SBYTE",
      82              :    "CHAR",
      83              :    "UINT16",
      84              :    "INT16",
      85              :    "UINT32",
      86              :    "INT32",
      87              :    "BOOL",
      88              :    "FLOAT",
      89              :    "DOUBLE",
      90              :    "BITFIELD",
      91              :    "STRING",
      92              :    "ARRAY",
      93              :    "STRUCT",
      94              :    "KEY",
      95              :    "LINK",
      96              :    "INT64",
      97              :    "UINT64"
      98              : };
      99              : 
     100              : ////////////////////////////////////////
     101              : 
     102              : struct Tag
     103              : {
     104              :    int event_id;
     105              :    std::string name;
     106              :    int offset;
     107              :    int arraySize;
     108              :    int typeSize;
     109              :    int typeCode;
     110              : };
     111              : 
     112              : struct Event
     113              : {
     114              :    bool printAllTags;
     115              :    int size;
     116              :    std::map<std::string,Tag*> tags;
     117              :    std::vector<std::string> tagNames;
     118              :    std::vector<int> tagIndexes;
     119              : };
     120              : 
     121              : std::map<int,Event*> gTags;
     122              : 
     123              : bool doPrintTags  = true;
     124              : bool doPrintNames = true;
     125              : bool doPrintData  = true;
     126              : bool doAll        = false;
     127              : 
     128            0 : int readHstFile(FILE*f)
     129              : {
     130            0 :    bool doRead = true;
     131              : 
     132            0 :    assert(f!=NULL);
     133              : 
     134              :    while (1)
     135              :       {
     136              :          HIST_RECORD rec;
     137              : 
     138            0 :          if (doRead)
     139              :             {
     140            0 :                int rd = fread(&rec, sizeof(rec), 1, f);
     141            0 :                if (!rd)
     142            0 :                   break;
     143              :             }
     144              : 
     145            0 :          doRead = true;
     146              : #if 0
     147              :          printf("HIST_RECORD:\n");
     148              :          printf("  Record type: 0x%x\n", rec.record_type);
     149              :          printf("  Event ID: %d\n", rec.event_id);
     150              :          printf("  Time: %d\n", rec.time);
     151              :          printf("  Offset: 0x%x\n", rec.def_offset);
     152              :          printf("  Size: 0x%x\n", rec.data_size);
     153              : #endif
     154              : 
     155            0 :          switch (rec.record_type)
     156              :             {
     157            0 :             default:
     158            0 :                printf("Unexpected record type: 0x%08x, trying to recover by skipping bad data.\n", rec.record_type);
     159              :                while (1)
     160              :                   {
     161            0 :                      int c = fgetc(f);
     162              :                      //printf("read 0x%02x\n", c);
     163            0 :                      if (c==EOF)
     164            0 :                         return 0;
     165            0 :                      if (c!=0x48)
     166            0 :                         continue;
     167              : 
     168            0 :                      c = fgetc(f);
     169            0 :                      if (c==EOF)
     170            0 :                         return 0;
     171            0 :                      if (c!=0x53)
     172            0 :                         continue;
     173              : 
     174            0 :                      c = fgetc(f);
     175            0 :                      if (c==EOF)
     176            0 :                         return 0;
     177            0 :                      if (c!=0x44)
     178            0 :                         continue;
     179              : 
     180            0 :                      printf("Maybe recovered - see what looks like valid history record header.\n");
     181              : 
     182            0 :                      ((char*)(&rec))[0] = 0x48;
     183            0 :                      ((char*)(&rec))[1] = 0x53;
     184            0 :                      ((char*)(&rec))[2] = 0x44;
     185              : 
     186            0 :                      int rd = fread(((char*)(&rec))+3, sizeof(rec)-3, 1, f);
     187            0 :                      if (!rd)
     188            0 :                         return 0;
     189              : 
     190            0 :                      doRead = false;
     191            0 :                      break;
     192            0 :                   }
     193            0 :                break;
     194              : 
     195            0 :             case 0x46445348: // RT_DEF:
     196              :                {
     197              :                   char event_name[NAME_LENGTH];
     198            0 :                   int rd = fread(event_name, 1, NAME_LENGTH, f);
     199            0 :                   assert(rd == NAME_LENGTH);
     200              :             
     201            0 :                   int size = rec.data_size;
     202            0 :                   int ntags = size/sizeof(TAG);
     203              : 
     204            0 :                   if (doPrintTags)
     205            0 :                      printf("Event %d, \"%s\", size %d, %d tags.\n", rec.event_id, event_name, size, ntags);
     206              : 
     207            0 :                   assert(size > 0);
     208            0 :                   assert(size < 1*1024*1024);
     209            0 :                   assert(size == ntags*(int)sizeof(TAG));
     210              :             
     211            0 :                   TAG *tags = new TAG[ntags];
     212            0 :                   rd = fread(tags, 1, size, f);
     213            0 :                   assert(rd == size);
     214              : 
     215            0 :                   Event* e = gTags[rec.event_id];
     216            0 :                   if (!e)
     217              :                      {
     218            0 :                         gTags[rec.event_id] = new Event;
     219            0 :                         e = gTags[rec.event_id];
     220            0 :                         e->printAllTags = false;
     221            0 :                         if (doAll)
     222            0 :                            e->printAllTags = true;
     223              :                      }
     224              :                   else
     225              :                      {
     226            0 :                         if (e->printAllTags) {
     227            0 :                            e->tagNames.clear();
     228            0 :                            e->tagIndexes.clear();
     229              :                         }
     230              :                      }
     231              : 
     232            0 :                   e->size = 0;
     233              : 
     234            0 :                   int offset = 0;
     235              : 
     236            0 :                   for (int itag=0; itag<ntags; itag++)
     237              :                      {
     238            0 :                         int tsize = tid_size[tags[itag].type];
     239              : 
     240            0 :                         if (tsize == 0)
     241            0 :                            tsize = 1;
     242              : 
     243            0 :                         int size = tags[itag].n_data * tsize;
     244              : 
     245            0 :                         if (tags[itag].type == 12) { // TID_STRING
     246              :                            //if (size == 1)
     247              :                            //size = 32; // kludge old broken history files
     248            0 :                            fprintf(stderr, "Error: Event %d, \"%s\", has a tag \"%s\" of type TID_STRING, which is forbidden and cannot be decoded, all data after this tag will be gibberish\n", rec.event_id, event_name, tags[itag].name);
     249            0 :                            size = 0;
     250              :                         }
     251              : 
     252            0 :                         if (offset%tsize != 0)
     253            0 :                            offset += tsize-offset%tsize;
     254              : 
     255            0 :                         assert(offset%tsize == 0);
     256              : 
     257            0 :                         Tag* t = new Tag;
     258            0 :                         t->event_id  = rec.event_id;
     259            0 :                         t->name      = tags[itag].name;
     260            0 :                         t->offset    = offset;
     261            0 :                         t->arraySize = tags[itag].n_data;
     262            0 :                         t->typeSize  = tid_size[tags[itag].type];
     263            0 :                         t->typeCode  = tags[itag].type;
     264              : 
     265            0 :                         e->tags[t->name] = t;
     266              : 
     267            0 :                         if (e->printAllTags)
     268              :                            {
     269            0 :                               e->tagNames.push_back(t->name);
     270            0 :                               e->tagIndexes.push_back(-1);
     271              :                            }
     272              : 
     273            0 :                         if (doPrintTags)
     274            0 :                            printf("  Tag %d: \"%s\"[%d], type \"%s\" (%d), type size %d, offset %d+%d\n", itag, tags[itag].name, tags[itag].n_data, tid_name[tags[itag].type], tags[itag].type, tid_size[tags[itag].type], offset, size);
     275              : 
     276            0 :                         offset += size;
     277              :                      }
     278              : 
     279            0 :                   e->size = offset;
     280              : 
     281              :                   //if (doPrintTags)
     282              :                   //printf("  Event size %d\n", e->size);
     283              : 
     284            0 :                   delete[] tags;
     285            0 :                   break;
     286              :                }
     287              : 
     288            0 :             case 0x41445348: // RT_DATA:
     289              :                {
     290            0 :                   int size = rec.data_size;
     291              : 
     292              :                   if (0)
     293              :                      printf("Data record, size %d.\n", size);
     294              : 
     295            0 :                   if (size <= 1 || size > 1*1024*1024)
     296              :                      {
     297            0 :                         fprintf(stderr, "Error: Invalid data record: event %d, size %d is invalid\n", rec.event_id, rec.data_size);
     298            0 :                         continue;
     299              :                      }
     300              :             
     301            0 :                   char *buf = new char[size];
     302            0 :                   int rd = fread(buf, 1, size, f);
     303            0 :                   assert(rd == size);
     304              : 
     305            0 :                   time_t t = (time_t)rec.time;
     306              : 
     307            0 :                   Event* e = gTags[rec.event_id];
     308            0 :                   if (e && doPrintData)
     309              :                      {
     310            0 :                         if (size != e->size)
     311              :                            {
     312            0 :                               fprintf(stderr, "Error: event %d, size mismatch should be %d, got %d bytes\n", rec.event_id, e->size, size);
     313              :                            }
     314              : 
     315              :                         //printf("event %d, time %s", rec.event_id, ctime(&t));
     316              : 
     317            0 :                         int n  = e->tagNames.size();
     318              : 
     319            0 :                         if (n>0)
     320            0 :                            printf("%d %d ", rec.event_id, rec.time);
     321              : 
     322            0 :                         for (int i=0; i<n; i++)
     323              :                            {
     324            0 :                               Tag*t = e->tags[e->tagNames[i]];
     325            0 :                               int index = e->tagIndexes[i];
     326              : 
     327              :                               //printf(" dump %s[%d] (%p)\n", e->tagNames[i].c_str(), e->tagIndexes[i], t);
     328              : 
     329            0 :                               if (t)
     330              :                                  {
     331            0 :                                     int offset = t->offset;
     332            0 :                                     void* ptr = (void*)(buf+offset);
     333              : 
     334            0 :                                     if (doPrintNames)
     335              :                                        {
     336            0 :                                           if (index < 0)
     337            0 :                                              printf(" %s=", t->name.c_str());
     338              :                                           else
     339            0 :                                              printf(" %s[%d]=", t->name.c_str(), index);
     340              :                                        }
     341              : 
     342            0 :                                     for (int j=0; j<t->arraySize; j++)
     343              :                                        {
     344            0 :                                           if (index >= 0)
     345            0 :                                              j = index;
     346              : 
     347            0 :                                           switch (t->typeCode)
     348              :                                              {
     349            0 :                                              default:
     350            0 :                                                 printf("unknownType%d ",t->typeCode);
     351            0 :                                                 break;
     352            0 :                                              case 1: /* BYTE */
     353            0 :                                                 printf("%u ",((uint8_t*)ptr)[j]);
     354            0 :                                                 break;
     355            0 :                                              case 2: /* SBYTE */
     356            0 :                                                 printf("%d ",((int8_t*)ptr)[j]);
     357            0 :                                                 break;
     358            0 :                                              case 3: /* CHAR */
     359            0 :                                                 printf("\'%c\' ",((char*)ptr)[j]);
     360            0 :                                                 break;
     361            0 :                                              case 4: /* WORD */
     362            0 :                                                 printf("%u ",((uint16_t*)ptr)[j]);
     363            0 :                                                 break;
     364            0 :                                              case 5: /* SHORT */
     365            0 :                                                 printf("%d ",((int16_t*)ptr)[j]);
     366            0 :                                                 break;
     367            0 :                                              case 6: /* DWORD */
     368            0 :                                                 printf("%u ",((uint32_t*)ptr)[j]);
     369            0 :                                                 break;
     370            0 :                                              case 7: /* INT */
     371            0 :                                                 printf("%d ",((int32_t*)ptr)[j]);
     372            0 :                                                 break;
     373            0 :                                              case 8: /* BOOL */
     374            0 :                                                 printf("%u ",((uint32_t*)ptr)[j]);
     375            0 :                                                 break;
     376            0 :                                              case 9: /* FLOAT */
     377            0 :                                                 printf("%.8g ",((float*)ptr)[j]);
     378            0 :                                                 break;
     379            0 :                                              case 10: /* DOUBLE */
     380            0 :                                                 printf("%.16g ",((double*)ptr)[j]);
     381            0 :                                                 break;
     382              :                                              //case 12: /* STRING */
     383              :                                                 //printf("%s ",&((char*)ptr)[j]);
     384              :                                                 //break;
     385              :                                              }
     386              : 
     387            0 :                                           if (index >= 0)
     388            0 :                                              break;
     389              :                                        }
     390              :                                  }
     391              :                            }
     392              : 
     393            0 :                         if (n>0)
     394            0 :                            printf(" %s", ctime(&t));
     395              :                      }
     396              : 
     397            0 :                   delete[] buf;
     398            0 :                   break;
     399              :                }
     400              :             }
     401            0 :       }
     402              : 
     403            0 :    return 0;
     404              : }
     405              : 
     406            0 : int readHst(const char* name)
     407              : {
     408            0 :    FILE* f = fopen(name,"r");
     409            0 :    if (!f)
     410              :       {
     411            0 :          fprintf(stderr,"Error: Cannot open \'%s\', errno %d (%s)\n", name, errno, strerror(errno));
     412            0 :          exit(1);
     413              :       }
     414              : 
     415            0 :    readHstFile(f);
     416            0 :    fclose(f);
     417            0 :    return 0;
     418              : }
     419              : 
     420            0 : std::string readString(FILE* f)
     421              : {
     422              :    char buf[1024];
     423            0 :    memset(buf, 0, sizeof(buf));
     424            0 :    const char* s = fgets(buf, sizeof(buf)-1, f);
     425            0 :    if (!s)
     426            0 :       return "";
     427              :    // NUL-teminated by memset(0)
     428            0 :    size_t len = strlen(buf);
     429            0 :    if (len > 0) {
     430              :       // remove trailing newline
     431            0 :       if (buf[len-1] == '\n')
     432            0 :          buf[len-1] = 0;
     433              :    }
     434            0 :    return buf;
     435              : }
     436              : 
     437            0 : std::string tagValue(const char* tag, const std::string& s)
     438              : {
     439            0 :    size_t len = strlen(tag);
     440            0 :    if (strncmp(s.c_str(), tag, len) == 0) {
     441            0 :       const char* sptr = s.c_str() + len;
     442            0 :       while (sptr[0] == ' ')
     443            0 :          sptr++;
     444            0 :       return sptr;
     445              :    }
     446            0 :    return "";
     447              : }
     448              : 
     449            0 : int readMhfFileV2(const char* filename, FILE*f)
     450              : {
     451            0 :    std::string event_name = tagValue("event_name:", readString(f));
     452            0 :    std::string time       = tagValue("time:", readString(f));
     453            0 :    printf("event name: [%s], time [%s]\n", event_name.c_str(), time.c_str());
     454            0 :    std::string s;
     455              :    while (1) {
     456            0 :       s = readString(f);
     457            0 :       if (strncmp(s.c_str(), "tag:", 4) != 0)
     458            0 :          break;
     459            0 :       printf("tag: %s\n", s.c_str());
     460              :    }
     461            0 :    std::string s_record_size = tagValue("record_size:", s);
     462            0 :    std::string s_data_offset = tagValue("data_offset:", readString(f));
     463            0 :    size_t record_size = atoi(s_record_size.c_str());
     464            0 :    size_t data_offset = atoi(s_data_offset.c_str());
     465              :    //record_size += 4; // 4 bytes of timestamp
     466            0 :    printf("record size: %zu, data offset: %zu\n", record_size, data_offset);
     467            0 :    int status = fseek(f, data_offset, SEEK_SET);
     468            0 :    if (status != 0) {
     469            0 :       fprintf(stderr, "%s: cannot seek to %zu, fseek() returned %d, errno %d (%s)\n", filename, data_offset, status, errno, strerror(errno));
     470            0 :       return -1;
     471              :    }
     472            0 :    char buf[record_size];
     473            0 :    int count = 0;
     474            0 :    uint32_t last_time = atoi(time.c_str());
     475            0 :    while (!feof(f)) {
     476            0 :       size_t rd = fread(buf, 1, record_size, f);
     477              :       //printf("read %zu\n", rd);
     478            0 :       if (rd == 0) {
     479              :          // EOF
     480            0 :          break;
     481            0 :       } else if (rd != record_size) {
     482              :          // short read
     483            0 :          fprintf(stderr, "%s: short read at the end of file, last data record is truncated from %zu to %zu bytes\n", filename, record_size, rd);
     484            0 :          break;
     485              :       }
     486            0 :       const uint32_t t = *(uint32_t*)&buf[0];
     487            0 :       printf("record %d, time %lu, incr %lu\n", count, (long unsigned int)t, (long unsigned int)(t-last_time));
     488            0 :       count++;
     489            0 :       if (t == last_time) {
     490            0 :          printf("duplicate time %lu -> %lu\n", (long unsigned int)last_time, (long unsigned int)t);
     491            0 :       } else if (t < last_time) {
     492            0 :          printf("non-monotonic time %lu -> %lu\n", (long unsigned int)last_time, (long unsigned int)t);
     493              :       }
     494            0 :       last_time = t;
     495              :    }
     496            0 :    fprintf(stderr, "%s: read %d records\n", filename, count);
     497            0 :    return 0;
     498            0 : }
     499              : 
     500            0 : int readMhfFile(const char* filename, FILE*f)
     501              : {
     502            0 :    std::string version = readString(f);
     503            0 :    if (version == "version: 2.0") {
     504            0 :       return readMhfFileV2(filename, f);
     505              :    }
     506              : 
     507            0 :    fprintf(stderr, "%s: unexpected file version: %s\n", filename, version.c_str());
     508            0 :    return -1;
     509            0 : }
     510              : 
     511            0 : int readMhf(const char* name)
     512              : {
     513            0 :    FILE* f = fopen(name,"r");
     514            0 :    if (!f) {
     515            0 :       fprintf(stderr,"Error: Cannot open \'%s\', errno %d (%s)\n", name, errno, strerror(errno));
     516            0 :       exit(1);
     517              :    }
     518              : 
     519            0 :    readMhfFile(name, f);
     520            0 :    fclose(f);
     521            0 :    return 0;
     522              : }
     523              : 
     524            0 : void help()
     525              : {
     526            0 :    fprintf(stderr,"Usage: mhdump [-h] [-L] [-n] [-t] [-E event_id] [-T tag_name] file1.hst file2.hst ...\n");
     527            0 :    fprintf(stderr,"Usage: mhdump [-L] [-n] [-t] [-T tag_name] mhf_file1.dat mhf_file2.dat ...\n");
     528            0 :    fprintf(stderr,"\n");
     529            0 :    fprintf(stderr,"Switches:\n");
     530            0 :    fprintf(stderr,"  -h --- print this help message\n");
     531            0 :    fprintf(stderr,"  -L --- list tag definitions only\n");
     532            0 :    fprintf(stderr,"  -t --- omit tag definitions\n");
     533            0 :    fprintf(stderr,"  -n --- omit variable names\n");
     534            0 :    fprintf(stderr,"\n");
     535            0 :    fprintf(stderr,"Examples:\n");
     536            0 :    fprintf(stderr,"  To list all existing tags: mhdump -L file1.hst file2.hst ...\n");
     537            0 :    fprintf(stderr,"  To show data for all events, all tags: mhdump file1.hst file2.hst ...\n");
     538            0 :    fprintf(stderr,"  To show all data for event 0: mhdump -E 0 file1.hst file2.hst ...\n");
     539            0 :    fprintf(stderr,"  To show data for event 0, tag \"State\": mhdump -n -E 0 -T State file1.hst file2.hst ...\n");
     540            0 :    fprintf(stderr,"  To show data for event 3, tag \"MCRT\", array index 5: mhdump -n -E 3 -T MCRT[5] file1.hst file2.hst ...\n");
     541            0 :    exit(1);
     542              : }
     543              : 
     544            0 : int main(int argc,char*argv[])
     545              : {
     546            0 :    int event_id = -1;
     547              : 
     548            0 :    if (argc <= 1)
     549            0 :       help(); // DOES NOT RETURN
     550              : 
     551            0 :    for (int iarg=1; iarg<argc; iarg++)
     552            0 :       if (strcmp(argv[iarg], "-h")==0)
     553              :          {
     554            0 :             help(); // DOES NOT RETURN
     555              :          }
     556            0 :       else if (strcmp(argv[iarg], "-E")==0)
     557              :          {
     558            0 :             iarg++;
     559            0 :             event_id = atoi(argv[iarg]);
     560            0 :             if (!gTags[event_id])
     561            0 :                gTags[event_id] = new Event;
     562            0 :             gTags[event_id]->printAllTags = true;
     563              :          }
     564            0 :       else if (strcmp(argv[iarg], "-T")==0)
     565              :          {
     566            0 :             iarg++;
     567            0 :             char *s = strchr(argv[iarg],'[');
     568            0 :             int index = -1;
     569            0 :             if (s)
     570              :                {
     571            0 :                   index = atoi(s+1);
     572            0 :                   *s = 0;
     573              :                }
     574              : 
     575            0 :             std::string name = argv[iarg];
     576              : 
     577            0 :             Event* e = gTags[event_id];
     578              : 
     579            0 :             if ((event_id<0) || !e)
     580              :                {
     581            0 :                   fprintf(stderr,"Error: expected \"-E event_id\" before \"-T ...\"\n");
     582            0 :                   exit(1);
     583              :                }
     584              : 
     585            0 :             e->printAllTags = false;
     586            0 :             e->tagNames.push_back(name);
     587            0 :             e->tagIndexes.push_back(index);
     588            0 :          }
     589            0 :       else if (strcmp(argv[iarg], "-t")==0)
     590            0 :          doPrintTags = false;
     591            0 :       else if (strcmp(argv[iarg], "-L")==0)
     592              :          {
     593            0 :             doPrintTags = true;
     594            0 :             doPrintData = false;
     595              :          }
     596            0 :       else if (strcmp(argv[iarg], "-A")==0)
     597            0 :          doAll = true;
     598            0 :       else if (strcmp(argv[iarg], "-n")==0)
     599            0 :          doPrintNames = false;
     600            0 :       else if (strncmp(argv[iarg], "mhf_", 4) == 0 || strstr(argv[iarg], "/mhf_")) {
     601              :          // read mhf_xxx.dat files
     602            0 :          if (gTags.size() == 0)
     603            0 :             doAll = true;
     604            0 :          readMhf(argv[iarg]);
     605              :       } else {
     606              :          // read xxx.hst files
     607            0 :          if (gTags.size() == 0)
     608            0 :             doAll = true;
     609            0 :          readHst(argv[iarg]);
     610              :       }
     611              : 
     612              :    // make leak sanitizer happy, delete everything we allocated.
     613            0 :    for (auto& ei: gTags) {
     614            0 :       if (ei.second) {
     615            0 :          for (auto& ti: ei.second->tags) {
     616            0 :             if (ti.second) {
     617            0 :                delete ti.second;
     618              :             }
     619              :          }
     620            0 :          ei.second->tags.clear();
     621            0 :          delete ei.second;
     622              :       }
     623              :    }
     624            0 :    gTags.clear();
     625              : 
     626            0 :    return 0;
     627              : }
     628              : 
     629              : /* emacs
     630              :  * Local Variables:
     631              :  * tab-width: 8
     632              :  * c-basic-offset: 3
     633              :  * indent-tabs-mode: nil
     634              :  * End:
     635              :  */
        

Generated by: LCOV version 2.0-1