Beispiel #1
0
int RFG_Filter_readDefFile( RFG_Filter* filter, int rank, uint8_t* r_isRankOff )
{
  char*    line;
  uint32_t lineno = 0;
  size_t   pos = 0;
  uint8_t  parse_err = 0;
  uint8_t  l_is_rank_off = 0;
  uint8_t  includes_current_rank = 1;

  if( !filter || !filter->file_name )
    return 0;

  /* reset filter rules */
  if( !RFG_Filter_reset( filter ) )
    return 0;

  /* get filter file content, if necessary */

  if( !filter->file_content )
  {
    if( !get_file_content( filter ) )
    {
      fprintf( stderr,
               "RFG_Filter_readDefFile(): Error: Could not read file '%s'\n",
               filter->file_name );
      return 0;
    }
  }

  /* allocate memory for line */

  line = ( char* )malloc( MAX_LINE_LEN * sizeof( char ) );
  if( !line ) return 0;

  /* read lines */
  while( !l_is_rank_off && !parse_err &&
         get_file_content_line( filter, line, MAX_LINE_LEN, &pos ) )
  {
    char* p;
    char* q;

    /* increment line number */
    lineno++;

    /* remove newline */
    if( strlen(line) > 0 && line[strlen(line)-1] == '\n' )
      line[strlen(line)-1] = '\0';

    /* remove leading and trailing spaces from line */
    vt_strtrim( line );

    /* cut possible comment from line */

    p = strchr( line, '#' );
    if( p ) *p = '\0';

    /* continue if line is empty */
    if( strlen( line ) == 0 )
      continue;

    if( line[0] == '@' )
    {
      int a = -1;
      int b = -1;
      uint8_t is_rank_off_rule = 0;

      /* check whether selected ranks shall be disabled */
      if( ( p = strstr( line, "--" ) ) )
      {
        /* cut "-- OFF" from line */
        *p = '\0';

        p += 2;
        while( *p == ' ' || *p == '\t' ) p++;
        q = p;
        while( *q != '\0' ) { *q = tolower( *q ); q++; }

        if( strcmp( p, "off" ) == 0 )
        {
          is_rank_off_rule = 1;
        }
        else
        {
          parse_err = 1;
          break;
        }
      }

      /* no specific rank given? */
      if( rank == -1 )
      {
        /* continue reading, if selected ranks shall be disabled
           (non-rank-specific filter rules can follow) */
        if( is_rank_off_rule )
          continue;
        /* otherwise, stop reading
           (all the following filter rules are rank-specific which will be
            read later) */
        else
          break;
      }

      /* parse rank selection
         If current rank is included, then read the following filter rules.
         Otherwise, jump to next @ clause. */

      p = line + 1;

      includes_current_rank = 0;

      while( 1 )
      {
        while( *p == ' ' || *p == '\t' ) p++;

        if( *p >= '0' && *p <= '9' )
        {
          errno = 0;
          a = strtol( p, &q, 10 );
          p = q;
          if( errno != 0 )
          {
            parse_err = 1;
            break;
          }
        }
        else if( *p == '-' && *(p+1) != '\0' && a != -1 )
        {
          p++;

          errno = 0;
          b = strtol( p, &q, 10 );
          p = q;
          if( errno != 0 )
          {
            parse_err = 1;
            break;
          }
        }
        else if( (*p == ';' || *p == ',') && a != -1 )
        {
          p++;

          if( a == rank || (a < rank && rank <= b ) )
          {
            includes_current_rank = 1;
            if( is_rank_off_rule )
            {
              l_is_rank_off = 1; /* deactivate this rank completely */
              break;
            }
          }
          else if( is_rank_off_rule )
          {
            includes_current_rank = 1;
          }

          a = b = -1;
        }
        else if( *p == '\0' && a != -1 )
        {
          if( a == rank || (a < rank && rank <= b ) )
          {
            includes_current_rank = 1;
            if( is_rank_off_rule )
              l_is_rank_off = 1; /* deactivate this rank completely */
          }
          else if( is_rank_off_rule )
          {
            includes_current_rank = 1;
          }

          break;
        }
        else
        {
          parse_err = 1;
          break;
        }
      }
    }
    else
    {
      int32_t  climit;
      uint32_t sbounds[2] = { 1, (uint32_t)-1 };
      uint8_t  flags = 0;
      uint8_t  is_cpath_rule = 0;
      uint32_t num_cpath_regions = 0;
      char*    cpath_regions[RFG_FILTER_MAX_CPATH_SIZE];

      /* search for '--'
         e.g. "func1;func2;func3 -- 1000 S:5-10 R"
                                 p
      */

      if( !( p = strstr( line, "--" ) ) )
      {
        parse_err = 1;
        break;
      }

      /* cut call limit, stack level bounds, and flags from line
         e.g.   "func1;func2;func3 -- 1000 S:5-10 R"
             => "func1;func2;func3"
      */
      *p = '\0';

      /* split remaining line at ' ' to get call limit, stack level bounds,
         and flags */

      if( !( p = strtok( p+2, " " ) ) )
      {
        parse_err = 1;
        break;
      }

      /* parse call limit */
      {
        long l_climit;

        l_climit = strtol( p, &q, 10 );
        if( p == q || l_climit == LONG_MIN || l_climit == LONG_MAX ||
            l_climit < -1 )
        {
          parse_err = 1;
          break;
        }

        climit = (int32_t)l_climit;
      }

      /* parse stack level bounds and flags */
      while( !parse_err && ( p = strtok( NULL, " " ) ) )
      {
        /* stack level bounds */
        if( strlen( p ) > 2 && tolower( *p ) == 's' && *(p+1) == ':' )
        {
          long l_bounds[2] = { 1 };

          p = p+2;

          /* parse maximum (or minimum) stack level bound */

          l_bounds[1] = strtol( p, &q, 10 );
          if( p == q || l_bounds[1] == LONG_MIN || l_bounds[1] == LONG_MAX ||
              l_bounds[1] < 1 )
          {
            parse_err = 1;
            break;
          }

          p = q;

          /* minimum stack level bound specified? */
          if( *p == '-' )
          {
            p++;
            l_bounds[0] = l_bounds[1];

            /* parse maximum stack level bound */

            l_bounds[1] = strtol( p, &q, 10 );
            if( p == q || l_bounds[1] == LONG_MIN || l_bounds[1] == LONG_MAX ||
                l_bounds[1] < l_bounds[0] )
            {
              parse_err = 1;
              break;
            }

            p = q;
          }

          if( strlen( p ) > 1 || ( *p != '\0' && *p != '\t' ) )
          {
            parse_err = 1;
            break;
          }

          sbounds[0] = (uint32_t)l_bounds[0];
          sbounds[1] = (uint32_t)l_bounds[1];
        }
        /* group flag */
        else if( strlen( p ) == 1 && tolower( *p ) == 'g' )
        {
          flags |= RFG_FILTER_FLAG_GROUP;
        }
        /* recursiveness flag */
        else if( strlen( p ) == 1 && tolower( *p ) == 'r' )
        {
          flags |= RFG_FILTER_FLAG_RECURSIVE;
        }
        /* call-path flag */
        else if( strlen( p ) == 1 && tolower( *p ) == 'c' )
        {
          is_cpath_rule = 1;
        }
        else
        {
          parse_err = 1;
          break;
        }
      }

      /* call-path flag must not be mixed with other flags
         (except recursiveness) or stack level bounds */
      parse_err = ( parse_err || ( is_cpath_rule &&
        ( ( flags != 0 && flags != RFG_FILTER_FLAG_RECURSIVE ) ||
          sbounds[0] != 1 || sbounds[1] != (uint32_t)-1 ) ) );

      if( parse_err )
        break;

      /* split line at ';' to get pattern/region names */

      p = strtok( line, ";" );
      do
      {
        char* pattern_or_rname;

        if( !p )
        {
          parse_err = 1;
          break;
        }

        pattern_or_rname = strdup( p );
        vt_strtrim( pattern_or_rname );

        if( *pattern_or_rname != '\0' && includes_current_rank )
        {
          if( is_cpath_rule )
          {
             /* max. number of regions in a call path exceeded? */
             if( num_cpath_regions + 1 > RFG_FILTER_MAX_CPATH_SIZE )
             {
                free( pattern_or_rname );
                parse_err = 1;
                break;
             }
             /* add region to array of call-path region names */
             cpath_regions[num_cpath_regions++] = pattern_or_rname;
          }
          else
          {
            /* add region filter rules */
            RFG_Filter_addRegionRules( filter, pattern_or_rname, climit,
                                       sbounds, flags );

            free( pattern_or_rname );
          }
        }
        else
        {
          free( pattern_or_rname );
        }

      } while( ( p = strtok( 0, ";" ) ) );

      if( is_cpath_rule )
      {
        if( !parse_err )
        {
          /* add call-path filter rules */
          RFG_Filter_addCallPathRules( filter, num_cpath_regions,
                                       (const char**)cpath_regions, climit,
                                       NULL, NULL );
        }

        /* free array of call-path region names */

        do free( cpath_regions[--num_cpath_regions] );
        while( num_cpath_regions > 0 );
      }
    }
  }

  free( line );

  if( parse_err )
  {
    fprintf( stderr, "%s:%u: Could not be parsed\n",
      filter->file_name, lineno );
    return 0;
  }

  if( r_isRankOff )
    *r_isRankOff = l_is_rank_off;

  return 1;
}
Beispiel #2
0
int RFG_Groups_readDefFile( RFG_Groups* groups )
{
    FILE*    f;
    char*    line;
    uint32_t lineno = 0;
    uint8_t  parse_err = 0;

    if( !groups )
        return 0;

    if( !groups->file_name )
        return 1;

    /* open group definition file */

    f = fopen( groups->file_name, "r" );
    if( !f )
    {
        fprintf( stderr,
                 "RFG_Groups_readDefFile(): Error: Could not open file '%s'\n",
                 groups->file_name );
        return 0;
    }

    line = ( char* )malloc( MAX_LINE_LEN * sizeof( char ) );
    if( !line )
    {
        fclose( f );
        return 0;
    }

    /* read lines */

    while( !parse_err && fgets( line, MAX_LINE_LEN, f ) )
    {
        char* group;
        char* p;

        /* increment line number */
        lineno++;

        /* remove newline */
        if( strlen( line ) > 0 && line[strlen(line)-1] == '\n' )
            line[strlen(line)-1] = '\0';

        /* remove leading and trailing spaces from line */
        vt_strtrim( line );

        /* cut possible comment from line */

        p = strchr( line, '#' );
        if( p )
            *p = '\0';

        /* continue if line is empty */
        if( strlen( line ) == 0 )
            continue;

        /* search for '='
           e.g. "GROUP=func1;func2;func3"
                      p
        */

        p = strchr( line, '=' );
        if( !p )
        {
            parse_err = 1;
            break;
        }

        /* cut group name from line
           e.g.   "GROUP=func1;func2;func3"
               => "GROUP"
        */

        *p = '\0';

        group = strdup( line );
        vt_strtrim( group );

        /* split remaining line at ';' to get pattern */

        p = strtok( p+1, ";" );
        do
        {
            char* pattern;

            if( !p )
            {
                parse_err = 1;
                break;
            }

            pattern = strdup( p );
            vt_strtrim( pattern );

            /* add group assignment */

            if( strlen( pattern ) > 0 )
                RFG_Groups_addAssign( groups, group, pattern );

            free( pattern );

        } while( ( p = strtok( 0, ";" ) ) );

        free( group );
    }

    if( parse_err )
    {
        fprintf( stderr, "%s:%u: Could not be parsed\n",
                 groups->file_name, lineno );
    }

    free( line );

    fclose( f );

    return parse_err ? 0 : 1;
}