From 0ea06cb3e8bd9ffd06e8255748414738e7d31da3 Mon Sep 17 00:00:00 2001
From: whh8b <whh8b@git.zephyr-software.com>
Date: Thu, 25 Sep 2014 16:08:53 +0000
Subject: [PATCH] Add additional options and statistics support.

---
 .gitattributes               |  3 ++
 include/zipr.h               |  9 ++--
 include/zipr_all.h           |  4 +-
 include/zipr_optimizations.h |  8 ++++
 include/zipr_options.h       | 28 +++++++-----
 include/zipr_stats.h         | 18 ++++++++
 src/Makefile                 |  2 +-
 src/main.cpp                 |  6 +++
 src/zipr.cpp                 |  1 +
 src/zipr_options.cpp         | 82 ++++++++++++++++++++++++++++++++++++
 10 files changed, 146 insertions(+), 15 deletions(-)
 create mode 100644 include/zipr_optimizations.h
 create mode 100644 include/zipr_stats.h
 create mode 100644 src/zipr_options.cpp

diff --git a/.gitattributes b/.gitattributes
index 9fd8d073f..b35d33929 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -4,10 +4,13 @@ include/range.h -text
 include/unresolved.h -text
 include/zipr.h -text
 include/zipr_all.h -text
+include/zipr_optimizations.h -text
 include/zipr_options.h -text
+include/zipr_stats.h -text
 src/Makefile -text
 src/main.cpp -text
 src/zipr.cpp -text
+src/zipr_options.cpp -text
 third_party/ELFIO/elfio-2.2/AUTHORS -text
 third_party/ELFIO/elfio-2.2/COPYING -text
 third_party/ELFIO/elfio-2.2/ChangeLog -text
diff --git a/include/zipr.h b/include/zipr.h
index 8db9c3a73..52cf61c0a 100644
--- a/include/zipr.h
+++ b/include/zipr.h
@@ -31,12 +31,14 @@
 #ifndef zipr_h
 #define zipr_h
 
+class Options_t;
+class Stats_t;
 
 class Zipr_t
 {
 	public:
-		Zipr_t(libIRDB::FileIR_t* p_firp, const Options_t &p_opts)
-			: m_firp(p_firp), m_opts(p_opts) 
+		Zipr_t(libIRDB::FileIR_t* p_firp, Options_t &p_opts)
+			: m_firp(p_firp), m_opts(p_opts)
 		{ 
                 	total_dollops=0;
                 	total_dollop_space=0;
@@ -55,7 +57,8 @@ class Zipr_t
 
 		// data for the stuff we're rewriting.
 		libIRDB::FileIR_t* m_firp;
-		const Options_t& m_opts;
+		Options_t& m_opts;
+		Stats_t *m_stats;
 
 		// phases of rewriting.
 		void FindFreeRanges(const std::string &name);
diff --git a/include/zipr_all.h b/include/zipr_all.h
index 753d8ae8f..3ec33419f 100644
--- a/include/zipr_all.h
+++ b/include/zipr_all.h
@@ -45,10 +45,12 @@
 namespace zipr
 {
 
-#include <zipr_options.h>
 #include <range.h>
 #include <unresolved.h>
 #include <zipr.h>
+#include <zipr_optimizations.h>
+#include <zipr_options.h>
+#include <zipr_stats.h>
 
 };
 
diff --git a/include/zipr_optimizations.h b/include/zipr_optimizations.h
new file mode 100644
index 000000000..0659335c7
--- /dev/null
+++ b/include/zipr_optimizations.h
@@ -0,0 +1,8 @@
+#ifndef zipr_optimizations_t
+#define zipr_optimizations_t
+
+class Optimizations_t {
+	public:
+		enum Optimization { OptimizationPlopNotJump = 0 , NumberOfOptimizations};
+};
+#endif
diff --git a/include/zipr_options.h b/include/zipr_options.h
index 6cb2fe019..b529ba95f 100644
--- a/include/zipr_options.h
+++ b/include/zipr_options.h
@@ -31,28 +31,36 @@
 #ifndef zipr_options_h
 #define zipr_options_h
 
+#include <zipr_all.h>
 #include <string>
-// #include <libIRDB-core.hpp>
+#include <unistd.h>
+#include <libIRDB-core.hpp>
 
 class Options_t 
 {
 	public:
-		Options_t() : m_outname("b.out") { };
+		Options_t() : m_outname("b.out") { }
+
+		static Options_t* parse_args(int p_argc, char* p_argv[]);
+		static void print_usage(int p_argc, char *p_argv[]);
 
-		static Options_t* parse_args(int p_argc, char* p_argv[]) 
-		{ 
-			Options_t *opt=new Options_t;
-			assert(opt);
-			opt->m_var_id=::atoi(p_argv[1]); 
-			return opt;
-		};
-		
 		std::string GetOutputFileName(libIRDB::File_t* p_file) { return m_outname; }
 		int GetVariantID() { return m_var_id; }
+		
+		void EnableOptimization(Optimizations_t::Optimization opt) 
+		{ 
+			EnabledOptimizations[opt] = 1; 
+		};
+
+		bool IsEnabledOptimization(Optimizations_t::Optimization opt) 
+		{ 
+			return EnabledOptimizations[opt] == 1; 
+		};
 
 	private:
 		std::string m_outname;
 		int m_var_id;
+		int EnabledOptimizations[Optimizations_t::NumberOfOptimizations];
 };
 
 #endif
diff --git a/include/zipr_stats.h b/include/zipr_stats.h
new file mode 100644
index 000000000..9f47fa917
--- /dev/null
+++ b/include/zipr_stats.h
@@ -0,0 +1,18 @@
+#ifndef zipr_stats_t
+#define zipr_stats_t
+
+class Stats_t
+{
+	public:
+		Stats_t() {
+			for (int i=0; i<Optimizations_t::NumberOfOptimizations; i++)
+			{
+				Hits[i] = Misses[i] = 0;
+			}
+		};
+		int Hits[Optimizations_t::NumberOfOptimizations];
+		int Misses[Optimizations_t::NumberOfOptimizations];
+		void Hit(Optimizations_t::Optimization opt) { Hits[opt]++; };
+		void Missed(Optimizations_t::Optimization opt) { Misses[opt]++; };
+};
+#endif
diff --git a/src/Makefile b/src/Makefile
index 484a9f909..8d8275908 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -3,7 +3,7 @@ INC=-I../include -I../third_party/ELFIO/elfio-2.2 -I$(SECURITY_TRANSFORMS_HOME)/
 
 
 
-SRCS=main.cpp zipr.cpp
+SRCS=zipr.cpp zipr_options.cpp main.cpp
 OBJS=$(subst .cpp,.o, $(SRCS))
 HDRS=../include/*.h 
 EXE=zipr.exe
diff --git a/src/main.cpp b/src/main.cpp
index 54779a54c..d114e813c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -53,6 +53,12 @@ int main(int argc, char* argv[])
         VariantID_t *pidp=NULL;
         FileIR_t * firp=NULL;
 
+	if ((!options->GetVariantID()))
+	{
+		Options_t::print_usage(argc, argv);
+		return 1;
+	}
+
         try
         {
                 /* setup the interface to the sql server */
diff --git a/src/zipr.cpp b/src/zipr.cpp
index 8bee38235..34d097de6 100644
--- a/src/zipr.cpp
+++ b/src/zipr.cpp
@@ -54,6 +54,7 @@ using namespace ELFIO;
 
 void Zipr_t::CreateBinaryFile(const std::string &name)
 {
+	m_stats = new Stats_t();
 
 	// create ranges, including extra range that's def. big enough.
 	FindFreeRanges(name);
diff --git a/src/zipr_options.cpp b/src/zipr_options.cpp
new file mode 100644
index 000000000..4ca05858a
--- /dev/null
+++ b/src/zipr_options.cpp
@@ -0,0 +1,82 @@
+#include <zipr_all.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+using namespace zipr;
+
+void Options_t::print_usage(int p_argc, char *p_argv[])
+{
+	printf("%s [options]\n", p_argv[0]);
+	printf("\t-v variant-id\t--variant variant-id: "
+		"Variant ID. Mandatory. Default: none.\n");
+	printf("\t-o file\t\t--output file: "
+		"Output file name. Optional. Default: b.out.\n");
+	printf("\t-z optimization\t--optimize optimization: "
+		"Enable an optimization. Repeatable. Optional. \n");
+}
+
+Options_t* Options_t::parse_args(int p_argc, char* p_argv[])
+{
+	extern char *optarg;
+	extern int optind, opterr, optopt;
+	int option = 0;
+	char options[] = "o:v:z:";
+	struct option long_options[] = {
+		{"output", 1, 0, 'o'},
+		{"variant", 1, 0, 'v'},
+		{"optimize", 0, 0, 'z'},
+		{0, 0, 0, 0},
+	};
+
+	Options_t *opt=new Options_t;
+	assert(opt);
+
+	while ((option = getopt_long(
+		p_argc, 
+		p_argv, 
+		options, 
+		long_options, 
+		NULL)) != -1)
+	{
+		switch (option) {
+			case 'z':
+			{
+				if (!strcmp("plopnotjump", ::optarg))
+				{
+					opt->EnableOptimization(
+						Optimizations_t::OptimizationPlopNotJump);
+				}
+				else
+				{
+					printf("Warning: Unrecognized optimization: %s\n", ::optarg);
+				}
+				break;
+			}
+			case 'o':
+			{
+				opt->m_outname = std::string(::optarg);
+				break;
+			}
+			case 'v':
+			{
+				char *valid = NULL;
+				long int variant_id = ::strtol(::optarg, 
+								&valid, 
+								10); 
+				if (*valid == '\0') {
+					opt->m_var_id = variant_id;
+					break;
+				}
+				printf("Error: Invalid variant id (%s).\n", ::optarg);
+				break;
+			}
+			default:
+			{
+				printf("Warning: Unrecognized option!\n");
+				break;
+			}
+		}
+	}
+	return opt;
+}
-- 
GitLab