#include <iostream>
#include <fstream>
#include <map>
#include <list>
#include <stdio.h>
#include <string>

using namespace std;

struct ltstr {
	bool operator()(const std::string a, const std::string b ) const
		{
			return ( a < b );
		}
};

typedef std::map < std::string, std::string, ltstr > CpuMap;
CpuMap oCpuMap;

// this holds each of the CPUs from /proc/cpuinfo
typedef std::list < CpuMap > CpuMapList;
CpuMapList oCpuMapList;

int main ( )
{

	ifstream cpuinfo ( "/proc/cpuinfo" );
	char NameBuffer [ 256 ];
	char ValueBuffer [ 256 ];
	char DiscardBuffer [ 256 ];

	// read in the contents of cpuinfo
	while ( ! cpuinfo.eof ( ) ) {
		
		
		cpuinfo.get ( NameBuffer, 256, ':' );

		// check if this is empty -- if it is, we're at the blank line between
		//   multiple processes
		if ( NameBuffer [ 0 ] == '\0' ) {

			oCpuMapList.push_back ( oCpuMap );
			oCpuMap.clear ( );

		}


		cpuinfo.get ( DiscardBuffer, 3 ); // lose the :
		cpuinfo.get ( ValueBuffer, 256, '\n' );
		cpuinfo.get ( DiscardBuffer, 2, ' ' ); // lose the \n -- specify ' ' or it will stop before the \n and not read it

		// lose trailing white space
		for ( char * i = NameBuffer + strlen ( NameBuffer ) - 1;
			  !isalnum ( *i );
			  i-- ) {
			*i = '\0';
		}
		  

		if ( NameBuffer [ 0 ] == 0 ) {
			break;
		} else {
			oCpuMap [ NameBuffer ] = ValueBuffer;
		}
		
	}

	// push on the last one
	oCpuMapList.push_back ( oCpuMap );


	printf ( "System has %d CPUs\n",
			 oCpuMapList.size ( ) ):

	for (  CpuMapList::iterator j = oCpuMapList.begin ( );
		   j != oCpuMapList.end ( );
		   j++ ) {
		
		for ( CpuMap::iterator i = (*j).begin ( );
			  i != (*j).end ( );
			  i++ ) {
			
			printf ( "'%s'=>'%s'\n", (*i).first.c_str ( ), (*i).second.c_str ( ) );
			
		}
	}

}

