From e43b1138296866795c5db1a6dcd123d312af1b46 Mon Sep 17 00:00:00 2001
From: James Ralph <ralph@icl.utk.edu>
Date: Wed, 23 Jul 2014 15:40:47 -0400
Subject: [PATCH 10/44] native_avail.c: Bug fixes and updates

Thanks to Gary Mohr
--------------------------------------------------
This patch fixes a couple of problems found in the papi_native_avail program.

First change fixes a problem introduced when the -validate option was added.  This
option causes events to get added to an event set but never removes them.  This change
will remove them if the add works.  This change also fixes a coverity detected error
where the return value from PAPI_destroy_eventset was being ignored.

Second change improves the delimitor check when separating the event description from
the event mask description.  The previous check only looked for a colon but some of the
event descriptions contain a colon so descriptions would get displayed incorrectly.  The
new check finds the "masks:" substring which is what papi inserts to separate these two
descriptions.

Third change adds code to allow the user to enter events of the form pmu:::event or
pmu::event when using the -e option in the program.
---
 src/utils/native_avail.c | 41 ++++++++++++++++++++++++++++++++---------
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/src/utils/native_avail.c b/src/utils/native_avail.c
index 2073ed7..59fc1b4 100644
--- a/src/utils/native_avail.c
+++ b/src/utils/native_avail.c
@@ -178,10 +178,15 @@ print_event( PAPI_event_info_t * info, int offset, int validate )
 	int EventSet = PAPI_NULL;
 
 	if (validate && PAPI_create_eventset (&EventSet) == PAPI_OK) {
-		if (PAPI_add_named_event (EventSet, info->symbol) != PAPI_OK) {
+		if (PAPI_add_named_event (EventSet, info->symbol) == PAPI_OK) {
+			PAPI_remove_named_event (EventSet, info->symbol);
+		} else {
+			na = 1;
+		}
+		if ( PAPI_destroy_eventset( &EventSet ) != PAPI_OK ) {
+			printf("**********  Call to destroy eventset failed when trying to validate event '%s'  **********\n", info->symbol);
 			na = 1;
 		}
-		PAPI_destroy_eventset (&EventSet);
 	}
 
 	/* indent by offset */
@@ -227,13 +232,19 @@ parse_unit_masks( PAPI_event_info_t * info )
 	if ( ( pmask = strchr( ptr, ':' ) ) == NULL ) {
 		return ( 0 );
 	}
-	memmove( info->symbol, pmask, ( strlen( pmask ) + 1 ) * sizeof ( char ) );
-	pmask = strchr( info->long_descr, ':' );
-	if ( pmask == NULL )
+	memmove( info->symbol, pmask, ( strlen(pmask) + 1 ) * sizeof(char) );
+
+	//  The description field contains the event description followed by a tag 'masks:'
+	//  and then the mask description (if there was a mask with this event).  The following
+	//  code isolates the mask description part of this information.
+
+	pmask = strstr( info->long_descr, "masks:" );
+	if ( pmask == NULL ) {
 		info->long_descr[0] = 0;
-	else
-		memmove( info->long_descr, pmask + sizeof ( char ),
-				 ( strlen( pmask ) + 1 ) * sizeof ( char ) );
+	} else {
+		pmask += 6;        // bump pointer past 'masks:' identifier in description
+		memmove( info->long_descr, pmask, (strlen(pmask) + 1) * sizeof(char) );
+	}
 	return ( 1 );
 }
 
@@ -295,8 +306,20 @@ main( int argc, char **argv )
 			 "Event name:", info.symbol);
 		 printf( "%-29s|%s|\n", "Description:", info.long_descr );
 
+		  /* handle the PAPI component-style events which have a component:::event type */
+		  char *ptr;
+		  if ((ptr=strstr(flags.name, ":::"))) {
+		    ptr+=3;
+		  /* handle libpfm4-style events which have a pmu::event type event name */
+		  } else if ((ptr=strstr(flags.name, "::"))) {
+		    ptr+=2;
+		  }
+		  else {
+		    ptr=flags.name;
+		  }
+
 		     /* if unit masks exist but none specified, process all */
-		     if ( !strchr( flags.name, ':' ) ) {
+		     if ( !strchr( ptr, ':' ) ) {
 			if ( PAPI_enum_event( &i, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ) {
 			   printf( "\nUnit Masks:\n" );
 			   do {
-- 
2.1.1

