#!/usr/bin/env python

def fetch_cols(fstream, split_char = ','):
    return fstream.readline().strip().split(split_char)


def read_struct(fstream):
    line = fstream.readline().strip()
    fragments = line.split(",")
    fragments = [x for x in fragments if x is not None]
    p = dict()
    if not len(fragments) >= 3:
        return None

    p["struct"] = fragments[0]
    p["info"] = fragments[1]
    p["num_lines"] = fragments[2]

    struct = None
    if p is not None and p["struct"] == "STRUCT":
        num_lines = int(p["num_lines"].strip())
        struct = {}
        for _ in range(num_lines):
            cols = fetch_cols(fstream)
            struct.update({cols[0]: cols[1:]})
    return struct


def read_table(fstream):
    pos = fstream.tell()
    line = fstream.readline().strip()
    fragments = line.split(",")
    fragments = [x for x in fragments if x is not None]
    p = dict()
    if not len(fragments) >= 4:
        return None

    p["table"] = fragments[0]
    p["group"] = fragments[1]
    p["set"] = fragments[2]
    p["num_lines"] = fragments[3]

    struct = None
    if p is not None and p["table"] == "TABLE":
        num_lines = int(p["num_lines"].strip())
        struct = {}
        header = fetch_cols(fstream)

        struct.update({header[0]: header[1:]})
        for _ in range(num_lines):
            cols = fetch_cols(fstream)
            struct.update({cols[0]: cols[1:]})
    else:
        fstream.seek(pos)

    return struct


def read_structs(fstream):
    struct = read_struct(fstream)
    while struct is not None:
        yield struct
        struct = read_struct(fstream)


def read_tables(fstream):
    table = read_table(fstream)
    while table is not None:
        yield table
        table = read_table(fstream)

def get_measurements(region, core_info, data):
    measurements = []
    for k in data:
        if k not in ["1", "Region Info", "Event", "Metric"]:
            clean_core_info = [x for x in core_info if x]
            cores = len(clean_core_info)
            slot = data[k]
            offset = len(slot) - cores
            if offset >= 0:
                for i in range(cores):
                    off_i = offset + i
                    core = core_info[i]
                    if core and slot[off_i]:
                        measurements.append((region, k, core, slot[off_i]))
    return measurements

def get_likwid_perfctr(infile):
    measurements = []
    with open(infile, 'r') as in_file:
        read_struct(in_file)
        for region_struct in read_structs(in_file):
            region = region_struct["1"][1]
            core_info = region_struct["Region Info"]
            measurements += get_measurements(region, core_info, region_struct)

            for table_struct in read_tables(in_file):
                core_info = None
                if "Event" in table_struct:
                    core_info = table_struct["Event"][1:]
                elif "Metric" in table_struct:
                    core_info = table_struct["Metric"]

                if core_info:
                    measurements += get_measurements(region, core_info,
                                                     table_struct)
                # print pprint(table_struct)

    return measurements

@@ -1813,16 +1813,34 @@
 fo, data
+, extra_offset = 0
 ):%0A    m
@@ -1860,96 +1860,8 @@
  %5B%5D%0A
-    for k in data:%0A        if k not in %5B%221%22, %22Region Info%22, %22Event%22, %22Metric%22%5D:%0A        
     
@@ -1906,24 +1906,16 @@
 o if x%5D%0A
-        
     core
@@ -1947,30 +1947,22 @@
     
-        slot =
+for k in
  data
-%5Bk%5D
+:
 %0A   
@@ -1970,38 +1970,73 @@
     
-    offset = len(slot) - cores
+if k not in %5B%221%22, %22Region Info%22, %22Event%22, %22Metric%22, %22CPU clock%22%5D:
 %0A   
@@ -2048,28 +2048,23 @@
     
-if offse
+slo
 t 
-%3E
 = 
-0:%0A    
+data%5Bk%5D%0A
     
@@ -2114,75 +2114,67 @@
     
-    off_i = offset + i%0A                    core = core_info%5Bi%5D%0A    
+core = core_info%5Bi%5D%0A                idx = extra_offset + i%0A
     
@@ -2206,20 +2206,14 @@
 lot%5B
-off_i%5D:%0A    
+idx%5D:%0A
     
@@ -2275,17 +2275,16 @@
 lot%5B
-off_i
+idx
 %5D))%0A
+%0A
     
@@ -2593,32 +2593,50 @@
  measurements +=
+ %5C%0A               
  get_measurement
@@ -2795,32 +2795,63 @@
 n table_struct:%0A
+                    offset = 1%0A
                 
@@ -2888,19 +2888,171 @@
 Event%22%5D%5B
-1:%5D
+offset:%5D%0A                    measurements += get_measurements(region, core_info,%0A                                                     table_struct, offset)
 %0A       
@@ -3149,39 +3149,8 @@
 ic%22%5D
-%0A%0A                if core_info:
 %0A   
@@ -3289,54 +3289,8 @@
 ct)%0A
-                # print pprint(table_struct)%0A%0A
     

parse all contents in the marker file