Ejemplo n.º 1
0
// str is a line of integers, starting with a line number.  Parse it,
// returning the first number in *lnno and the rest in a newly
// allocated Counts struct.  If lnno is non-NULL, treat the first
// number as a line number and assign it to *lnno instead of
// incorporating it in the counts array.
static 
Counts* splitUpCountsLine ( SOURCE* s, /*OUT*/UWord* lnno, const char* str )
{
   Bool    ok;
   Counts* counts;
   ULong   *tmpC = NULL;
   UInt     n_tmpC = 0, tmpCsize = 0;
   while (1) {
      if (n_tmpC >= tmpCsize) {
         tmpCsize += 50;
         tmpC = realloc(tmpC, tmpCsize * sizeof *tmpC);
         if (tmpC == NULL)
            mallocFail(s, "splitUpCountsLine:");
      }
      ok = parse_ULong( &tmpC[n_tmpC], &str );
      if (!ok)
         break;
      n_tmpC++;
   }
   if (*str != 0)
      parseError(s, "garbage in counts line");
   if (lnno ? (n_tmpC < 2) : (n_tmpC < 1))
      parseError(s, "too few counts in count line");

   if (lnno) {
      *lnno = (UWord)tmpC[0];
      counts = new_Counts( n_tmpC-1, /*COPIED*/&tmpC[1] );
   } else {
      counts = new_Counts( n_tmpC, /*COPIED*/&tmpC[0] );
   }
   free(tmpC);

   return counts;
}
Ejemplo n.º 2
0
// Read a line. Return the line read, or NULL if at EOF.
// The line is allocated dynamically but will be overwritten with
// every invocation. Caller must not free it.
static const char *readline ( SOURCE* s )
{
   static char  *line = NULL;
   static size_t linesiz = 0;

   int ch, i = 0;

   while (1) {
      ch = getc(s->fp);
      if (ch != EOF) {
          if (i + 1 >= linesiz) {
             linesiz += 500;
             line = realloc(line, linesiz * sizeof *line);
             if (line == NULL)
                mallocFail(s, "readline:");
          }
          line[i++] = ch;
          line[i] = 0;
          if (ch == '\n') {
             line[i-1] = 0;
             s->lno++;
             break;
          }
      } else {
         if (ferror(s->fp)) {
            perror(argv0);
            barf(s, "I/O error while reading input file");
         } else {
            // hit EOF
            break;
         }
      }
   }
   return i == 0 ? NULL : line;
}
Ejemplo n.º 3
0
/*---------------------------------------------*/
static BitStream* bsOpenWriteStream ( FILE* stream )
{
   BitStream *bs = malloc ( sizeof(BitStream) );
   if (bs == NULL) mallocFail ( sizeof(BitStream) );
   bs->handle = stream;
   bs->buffer = 0;
   bs->buffLive = 0;
   bs->mode = 'w';
   return bs;
}
Ejemplo n.º 4
0
static
void handle_counts ( SOURCE* s,
                     CacheProfFile* cpf,
                     char* fi, char* fn, char* newCountsStr )
{
    WordFM* countsMap;
    Bool    freeNewCounts;
    UWord   lnno;
    Counts* newCounts;
    FileFn* topKey;

    if (0)  printf("%s %s %s\n", fi, fn, newCountsStr );

    // parse the numbers
    newCounts = splitUpCountsLine( s, &lnno, newCountsStr );

    // Did we get the right number?
    if (newCounts->n_counts != cpf->n_events)
        goto oom;

    // allocate the key
    topKey = malloc(sizeof(FileFn));
    if (topKey) {
        topKey->fi_name = strdup(fi);
        topKey->fn_name = strdup(fn);
    }
    if (! (topKey && topKey->fi_name && topKey->fn_name))
        mallocFail(s, "handle_counts:");

    // search for it
    if (lookupFM( cpf->outerMap, (Word*)(&countsMap), (Word)topKey )) {
        // found it.  Merge in new counts
        freeNewCounts = addCountsToMap( s, countsMap, lnno, newCounts );
        ddel_FileFn(topKey);
    } else {
        // not found in the top map.  Create new entry
        countsMap = newFM( malloc, free, cmp_unboxed_UWord );
        if (!countsMap)
            goto oom;
        addToFM( cpf->outerMap, (Word)topKey, (Word)countsMap );
        freeNewCounts = addCountsToMap( s, countsMap, lnno, newCounts );
    }

    // also add to running summary total
    addCounts( s, cpf->summary, newCounts );

    // if safe to do so, free up the count vector
    if (freeNewCounts)
        ddel_Counts(newCounts);

    return;

oom:
    parseError(s, "# counts doesn't match # events");
}
Ejemplo n.º 5
0
static void merge_CacheProfInfo ( SOURCE* s,
                                  /*MOD*/CacheProfFile* dst,
                                  CacheProfFile* src )
{
    /* For each (filefn, innerMap) in src
       if filefn not in dst
          add binding dopy(filefn)->dopy(innerMap) in src
       else
          // merge src->innerMap with dst->innerMap
          for each (lineno, counts) in src->innerMap
          if lineno not in dst->innerMap
             add binding lineno->dopy(counts) to dst->innerMap
          else
             add counts into dst->innerMap[lineno]
    */
    /* Outer iterator:  FileFn* -> WordFM* (inner iterator)
       Inner iterator:  UWord   -> Counts*
    */
    FileFn* soKey;
    WordFM* soVal;
    WordFM* doVal;
    UWord   siKey;
    Counts* siVal;
    Counts* diVal;

    /* First check mundane things: that the events: lines are
       identical. */
    if (!streq( dst->events_line, src->events_line ))
        barf(s, "\"events:\" line of most recent file does "
             "not match those previously processed");

    initIterFM( src->outerMap );

    // for (filefn, innerMap) in src
    while (nextIterFM( src->outerMap, (Word*)&soKey, (Word*)&soVal )) {

        // is filefn in dst?
        if (! lookupFM( dst->outerMap, (Word*)&doVal, (Word)soKey )) {

            // no .. add dopy(filefn) -> dopy(innerMap) to src
            FileFn* c_soKey = dopy_FileFn(soKey);
            WordFM* c_soVal = dopy_InnerMap(soVal);
            if ((!c_soKey) || (!c_soVal)) goto oom;
            addToFM( dst->outerMap, (Word)c_soKey, (Word)c_soVal );

        } else {

            // yes .. merge the two innermaps
            initIterFM( soVal );

            // for (lno, counts) in soVal (source inner map)
            while (nextIterFM( soVal, (Word*)&siKey, (Word*)&siVal )) {

                // is lno in the corresponding dst inner map?
                if (! lookupFM( doVal, (Word*)&diVal, siKey )) {

                    // no .. add lineno->dopy(counts) to dst inner map
                    Counts* c_siVal = dopy_Counts( siVal );
                    if (!c_siVal) goto oom;
                    addToFM( doVal, siKey, (Word)c_siVal );

                } else {

                    // yes .. merge counts into dst inner map val
                    addCounts( s, diVal, siVal );

                }
            }

        }

    }

    // add the summaries too
    addCounts(s, dst->summary, src->summary );

    return;

oom:
    mallocFail(s, "merge_CacheProfInfo");
}
Ejemplo n.º 6
0
/* Parse a complete file from the stream in 's'.  If a parse error
   happens, do not return; instead exit via parseError().  If an
   out-of-memory condition happens, do not return; instead exit via
   mallocError().
*/
static CacheProfFile* parse_CacheProfFile ( SOURCE* s )
{
#define M_TMP_DESCLINES 10

    Int            i;
    Bool           b;
    char*          tmp_desclines[M_TMP_DESCLINES];
    char*          p;
    int            n_tmp_desclines = 0;
    CacheProfFile* cpf;
    Counts*        summaryRead;
    char*          curr_fn_init = "???";
    char*          curr_fl_init = "???";
    char*          curr_fn      = curr_fn_init;
    char*          curr_fl      = curr_fl_init;

    cpf = new_CacheProfFile( NULL, NULL, NULL, 0, NULL, NULL, NULL );
    if (cpf == NULL)
        mallocFail(s, "parse_CacheProfFile(1)");

    // Parse "desc:" lines
    while (1) {
        b = readline(s);
        if (!b)
            break;
        if (!streqn(line, "desc: ", 6))
            break;
        if (n_tmp_desclines >= M_TMP_DESCLINES)
            barf(s, "M_TMP_DESCLINES too low; increase and recompile");
        tmp_desclines[n_tmp_desclines++] = strdup(line);
    }

    if (n_tmp_desclines == 0)
        parseError(s, "parse_CacheProfFile: no DESC lines present");

    cpf->desc_lines = malloc( (1+n_tmp_desclines) * sizeof(char*) );
    if (cpf->desc_lines == NULL)
        mallocFail(s, "parse_CacheProfFile(2)");

    cpf->desc_lines[n_tmp_desclines] = NULL;
    for (i = 0; i < n_tmp_desclines; i++)
        cpf->desc_lines[i] = tmp_desclines[i];

    // Parse "cmd:" line
    if (!streqn(line, "cmd: ", 5))
        parseError(s, "parse_CacheProfFile: no CMD line present");

    cpf->cmd_line = strdup(line);
    if (cpf->cmd_line == NULL)
        mallocFail(s, "parse_CacheProfFile(3)");

    // Parse "events:" line and figure out how many events there are
    b = readline(s);
    if (!b)
        parseError(s, "parse_CacheProfFile: eof before EVENTS line");
    if (!streqn(line, "events: ", 8))
        parseError(s, "parse_CacheProfFile: no EVENTS line present");

    // figure out how many events there are by counting the number
    // of space-alphanum transitions in the events_line
    cpf->events_line = strdup(line);
    if (cpf->events_line == NULL)
        mallocFail(s, "parse_CacheProfFile(3)");

    cpf->n_events = 0;
    assert(cpf->events_line[6] == ':');
    for (p = &cpf->events_line[6]; *p; p++) {
        if (p[0] == ' ' && isalpha(p[1]))
            cpf->n_events++;
    }

    // create the running cross-check summary
    cpf->summary = new_Counts_Zeroed( cpf->n_events );
    if (cpf->summary == NULL)
        mallocFail(s, "parse_CacheProfFile(4)");

    // create the outer map (file+fn name --> inner map)
    cpf->outerMap = newFM ( malloc, free, cmp_FileFn );
    if (cpf->outerMap == NULL)
        mallocFail(s, "parse_CacheProfFile(5)");

    // process count lines
    while (1) {
        b = readline(s);
        if (!b)
            parseError(s, "parse_CacheProfFile: eof before SUMMARY line");

        if (isdigit(line[0])) {
            handle_counts(s, cpf, curr_fl, curr_fn, line);
            continue;
        }
        else if (streqn(line, "fn=", 3)) {
            if (curr_fn != curr_fn_init)
                free(curr_fn);
            curr_fn = strdup(line+3);
            continue;
        }
        else if (streqn(line, "fl=", 3)) {
            if (curr_fl != curr_fl_init)
                free(curr_fl);
            curr_fl = strdup(line+3);
            continue;
        }
        else if (streqn(line, "summary: ", 9)) {
            break;
        }
        else
            parseError(s, "parse_CacheProfFile: unexpected line in main data");
    }

    // finally, the "summary:" line
    if (!streqn(line, "summary: ", 9))
        parseError(s, "parse_CacheProfFile: missing SUMMARY line");

    cpf->summary_line = strdup(line);
    if (cpf->summary_line == NULL)
        mallocFail(s, "parse_CacheProfFile(6)");

    // there should be nothing more
    b = readline(s);
    if (b)
        parseError(s, "parse_CacheProfFile: "
                   "extraneous content after SUMMARY line");

    // check the summary counts are as expected
    summaryRead = splitUpCountsLine( s, NULL, &cpf->summary_line[8] );
    if (summaryRead == NULL)
        mallocFail(s, "parse_CacheProfFile(7)");
    if (summaryRead->n_counts != cpf->n_events)
        parseError(s, "parse_CacheProfFile: wrong # counts in SUMMARY line");
    for (i = 0; i < summaryRead->n_counts; i++) {
        if (summaryRead->counts[i] != cpf->summary->counts[i]) {
            parseError(s, "parse_CacheProfFile: "
                       "computed vs stated SUMMARY counts mismatch");
        }
    }
    free(summaryRead->counts);
    sdel_Counts(summaryRead);

    // since the summary counts are OK, free up the summary_line text
    // which contains the same info.
    if (cpf->summary_line) {
        free(cpf->summary_line);
        cpf->summary_line = NULL;
    }

    if (curr_fn != curr_fn_init)
        free(curr_fn);
    if (curr_fl != curr_fl_init)
        free(curr_fl);

    // All looks OK
    return cpf;

#undef N_TMP_DESCLINES
}