text: /* 
   *------------------------------------------------------------------
   * Copyright (c) 2006-2016 Cisco and/or its affiliates.
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at:
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  #include <stdio.h>
  #include <stdlib.h>
  #include <netinet/in.h>
  #include <string.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  #include <sys/fcntl.h>
  #include <sys/mman.h>
  #include <unistd.h>
  #include <ctype.h>
  #include <vppinfra/clib.h>
  #include <vppinfra/vec.h>
  #include <vppinfra/hash.h>
  #include <vppinfra/elog.h>
  #include <vppinfra/mem.h>
  #include <pwd.h>
  #include <stdarg.h>
  #include <time.h>
  #include "cpel.h"
  #include "cpel_util.h"
  
  static elog_main_t elog_main;
  
  /*
   * convert_clib_file
   */
  void convert_clib_file(char *clib_file)
  {
      clib_error_t *error = 0;
      int i;
      elog_main_t *em = &elog_main;
      double starttime, delta;
  
      error = elog_read_file (&elog_main, clib_file);
  
      if (error) {
          clib_warning("%U", format_clib_error, error);
          exit (1);
      }
  
      em = &elog_main;
  
      starttime = em->events[0].time;
  
      for (i = 0; i < vec_len (em->events); i++) {
          elog_event_t *e;        /* clib event */
          evt_t *ep;              /* xxx2cpel event */
          u8 *s;
          u64 timestamp;
          elog_event_type_t *t;
          u8 *brief_event_name;
          u8 *track_name;
          int j;
  
          e = vec_elt_at_index(em->events, i);
  
          /* Seconds since start of log */
          delta = e->time - starttime;
          
          /* u64 nanoseconds since start of log */
          timestamp = delta * 1e9;
  
          s = format (0, "%U%c", format_elog_event, em, e, 0);
  
          /* allocate an event instance */
          vec_add2(the_events, ep, 1);
          ep->timestamp = timestamp;
          
          /* convert string event code to a real number */
          t = vec_elt_at_index (em->event_types, e->type);
  
          /* 
           * Construct a reasonable event name.
           * Truncate the format string at the first whitespace break
           * or printf format character.
           */
          brief_event_name = format (0, "%s", t->format);
  
          for (j = 0; j < vec_len (brief_event_name); j++) {
              if (brief_event_name[j] == ' ' ||
                  brief_event_name[j] == '%' ||
                  brief_event_name[j] == '(') {
                  brief_event_name[j] = 0;
                  break;
              }
          }
          /* Throw away that much of the formatted event */
          vec_delete (s, j+1, 0);
  
          ep->event_id = find_or_add_event(brief_event_name, "%s");
  
          track_name = format (0, "%U%c", format_elog_track_name, em, e, 0);
  
          ep->track_id = find_or_add_track (track_name);
  
          ep->datum = find_or_add_strtab(s);
  
          vec_free (track_name);
          vec_free(brief_event_name);
          vec_free(s);
      }
  }
  
  u8 *vec_basename (char *s)
  {
      u8 * rv;
      char *cp = s;
  
      while (*cp)
          cp++;
  
      cp--;
  
      while (cp > s && *cp != '/')
          cp--;
  
      if (cp > s)
          cp++;
  
      rv = format (0, "%s", cp);
      return rv;
  }
  
  
  int event_compare (const void *a0, const void *a1)
  {
      evt_t *e0 = (evt_t *)a0;
      evt_t *e1 = (evt_t *)a1;
  
      if (e0->timestamp < e1->timestamp)
          return -1;
      else if (e0->timestamp > e1->timestamp)
          return 1;
      return 0;
  }
  
  int main (int argc, char **argv)
  {
      int curarg=1;
      char **inputfiles = 0;
      char *outputfile = 0;
      FILE *ofp;
  
      clib_mem_init_thread_safe (0, 256 << 20);
  
      if (argc < 3)
          goto usage;
  
      while (curarg < argc) {
          if (!strncmp(argv[curarg], "--input-file", 3)) {
              curarg++;
              if (curarg < argc) {
                  vec_add1 (inputfiles, argv[curarg]);
                  curarg++;
                  continue;
              }
              clib_warning("Missing filename after --input-file\n");
              exit (1);
          }
  
          if (!strncmp(argv[curarg], "--output-file", 3)) {
              curarg ++;
              if (curarg < argc) {
                  outputfile = argv[curarg];
                  curarg ++;
                  continue;
              }
              clib_warning("Missing filename after --output-file\n");
              exit(1);
          }
          vec_add1 (inputfiles, argv[curarg]);
          curarg++;
          continue;
  
      usage:
          fformat(stderr, 
                  "c2cpel [--input-file] <filename> --output-file <filename>\n");
          exit(1);
      }
  
      if (vec_len(inputfiles) == 0 || outputfile == 0)
          goto usage;
          
      if (vec_len(inputfiles) > 1)
          goto usage;
  
      clib_mem_init (0, ((uword)3<<30));
  
      cpel_util_init();
  
      convert_clib_file (inputfiles[0]);
  
      ofp = fopen (outputfile, "w");
      if (ofp == NULL) {
          clib_unix_warning ("couldn't create %s", outputfile);
          exit (1);
      }
      
      alpha_sort_tracks();
      fixup_event_tracks();
  
      /*
       * Four sections: string-table, event definitions, track defs, events. 
       */
      if (!write_cpel_header(ofp, 4)) {
          clib_warning ("Error writing cpel header to %s...\n", outputfile);
          unlink(outputfile);
          exit(1);
      }
  
      if (!write_string_table(ofp)) {
          clib_warning ("Error writing string table to %s...\n", outputfile);
          unlink(outputfile);
          exit(1);
      }
  
      if (!write_event_defs(ofp)) {
          clib_warning ("Error writing event defs to %s...\n", outputfile);
          unlink(outputfile);
          exit(1);
      }
  
      if (!write_track_defs(ofp)) {
          clib_warning ("Error writing track defs to %s...\n", outputfile);
          unlink(outputfile);
          exit(1);
      }
  
      if (!write_events(ofp, (u64) 1e9)) {
          clib_warning ("Error writing events to %s...\n", outputfile);
          unlink(outputfile);
          exit(1);
          
      }
      fclose(ofp);
      exit (0);
  }
  