Add --output-format command line option

Right now we have normal, terse, and json output. Lets add a parameter
that controls how to output results, instead of having options for
both terse and json outputs. If we are going to add a 4th output
type in the future, it's only going to get more messy.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/README b/README
index a135017..535b077 100644
--- a/README
+++ b/README
@@ -125,8 +125,9 @@
 	--latency-log		Generate per-job latency logs
 	--bandwidth-log		Generate per-job bandwidth logs
 	--minimal		Minimal (terse) output
-	--version		Print version info and exit
+	--output-format=type	Output format (terse,json,normal)
 	--terse-version=type	Terse version output format (default 3, or 2 or 4).
+	--version		Print version info and exit
 	--help			Print this page
 	--cmdhelp=cmd		Print command help, "all" for all of them
 	--enghelp=engine	Print ioengine help, or list available ioengines
diff --git a/backend.c b/backend.c
index 9b0d791..ce0a009 100644
--- a/backend.c
+++ b/backend.c
@@ -1381,7 +1381,7 @@
 
 	set_sig_handlers();
 
-	if (!terse_output) {
+	if (output_format == FIO_OUTPUT_NORMAL) {
 		log_info("Starting ");
 		if (nr_thread)
 			log_info("%d thread%s", nr_thread,
diff --git a/client.c b/client.c
index 50c1704..93c7103 100644
--- a/client.c
+++ b/client.c
@@ -733,7 +733,7 @@
 		log_info("\nDisk stats (read/write):\n");
 	}
 
-	print_disk_util(&du->dus, &du->agg, terse_output);
+	print_disk_util(&du->dus, &du->agg, output_format == FIO_OUTPUT_TERSE);
 }
 
 static void convert_jobs_eta(struct jobs_eta *je)
diff --git a/eta.c b/eta.c
index 1caee49..075ce8c 100644
--- a/eta.c
+++ b/eta.c
@@ -264,7 +264,9 @@
 	static struct timeval rate_prev_time, disp_prev_time;
 
 	if (!force) {
-		if (temp_stall_ts || terse_output || eta_print == FIO_ETA_NEVER)
+		if (output_format != FIO_OUTPUT_NORMAL)
+			return 0;
+		if (temp_stall_ts || eta_print == FIO_ETA_NEVER)
 			return 0;
 
 		if (!isatty(STDOUT_FILENO) && (eta_print != FIO_ETA_ALWAYS))
diff --git a/filesetup.c b/filesetup.c
index c284071..64da8bb 100644
--- a/filesetup.c
+++ b/filesetup.c
@@ -792,7 +792,7 @@
 	 */
 	if (need_extend) {
 		temp_stall_ts = 1;
-		if (!terse_output)
+		if (output_format == FIO_OUTPUT_NORMAL)
 			log_info("%s: Laying out IO file(s) (%u file(s) /"
 				 " %lluMB)\n", td->o.name, need_extend,
 					extend_size >> 20);
diff --git a/fio.h b/fio.h
index 0064a1d..b2bbe93 100644
--- a/fio.h
+++ b/fio.h
@@ -526,7 +526,7 @@
 extern unsigned int nr_process, nr_thread;
 extern int shm_id;
 extern int groupid;
-extern int terse_output;
+extern int output_format;
 extern int temp_stall_ts;
 extern unsigned long long mlock_size;
 extern uintptr_t page_mask, page_size;
@@ -761,4 +761,10 @@
 extern const char *fio_get_arch_string(int);
 extern const char *fio_get_os_string(int);
 
+enum {
+	FIO_OUTPUT_TERSE	= 0,
+	FIO_OUTPUT_JSON,
+	FIO_OUTPUT_NORMAL,
+};
+
 #endif
diff --git a/init.c b/init.c
index ca8047b..da1f472 100644
--- a/init.c
+++ b/init.c
@@ -36,7 +36,7 @@
 struct thread_data *threads = NULL;
 
 int exitall_on_terminate = 0;
-int terse_output = 0;
+int output_format = FIO_OUTPUT_NORMAL;
 int eta_print;
 unsigned long long mlock_size = 0;
 FILE *f_out = NULL;
@@ -117,9 +117,9 @@
 		.val		= 'm' | FIO_CLIENT_FLAG,
 	},
 	{
-		.name		= (char *) "json-output",
+		.name		= (char *) "output-format",
 		.has_arg	= optional_argument,
-		.val		= 'J' | FIO_CLIENT_FLAG,
+		.val		= 'F' | FIO_CLIENT_FLAG,
 	},
 	{
 		.name		= (char *) "version",
@@ -875,7 +875,7 @@
 	if (!td->o.name)
 		td->o.name = strdup(jobname);
 
-	if (!terse_output) {
+	if (output_format == FIO_OUTPUT_NORMAL) {
 		if (!job_add_num) {
 			if (!strcmp(td->io_ops->name, "cpuio")) {
 				log_info("%s: ioengine=cpu, cpuload=%u,"
@@ -1218,8 +1218,9 @@
 	printf("  --latency-log\t\tGenerate per-job latency logs\n");
 	printf("  --bandwidth-log\tGenerate per-job bandwidth logs\n");
 	printf("  --minimal\t\tMinimal (terse) output\n");
-	printf("  --version\t\tPrint version info and exit\n");
+	printf("  --output-format=x\tOutput format (terse,json,normal)\n");
 	printf("  --terse-version=x\tSet terse version output format to 'x'\n");
+	printf("  --version\t\tPrint version info and exit\n");
 	printf("  --help\t\tPrint this page\n");
 	printf("  --cmdhelp=cmd\t\tPrint command help, \"all\" for all of"
 		" them\n");
@@ -1411,11 +1412,17 @@
 			f_err = f_out;
 			break;
 		case 'm':
-			terse_output = 1;
+			output_format = FIO_OUTPUT_TERSE;
 			break;
-		case 'J':
-			terse_version = 4;
-			terse_output = 1;
+		case 'F':
+			if (!strcmp(optarg, "minimal") ||
+			    !strcmp(optarg, "terse") ||
+			    !strcmp(optarg, "csv"))
+				output_format = FIO_OUTPUT_TERSE;
+			else if (!strcmp(optarg, "json"))
+				output_format = FIO_OUTPUT_JSON;
+			else
+				output_format = FIO_OUTPUT_NORMAL;
 			break;
 		case 'h':
 			if (!cur_client) {
@@ -1448,10 +1455,9 @@
 			}
 			break;
 		case 'V':
-			if (terse_version == 4)
-				break;
 			terse_version = atoi(optarg);
-			if (!(terse_version == 2 || terse_version == 3)) {
+			if (!(terse_version == 2 || terse_version == 3) ||
+			     (terse_version == 4)) {
 				log_err("fio: bad terse version format\n");
 				exit_val = 1;
 				do_exit++;
@@ -1687,7 +1693,7 @@
 		fio_gtod_cpu = def_thread.o.gtod_cpu;
 	}
 
-	if (!terse_output)
+	if (output_format == FIO_OUTPUT_NORMAL)
 		log_info("%s\n", fio_version_string);
 
 	return 0;
diff --git a/json.c b/json.c
index 707ea14..8efbbda 100644
--- a/json.c
+++ b/json.c
@@ -96,9 +96,9 @@
 	return value;
 }
 
-static void json_free_array(struct json_array *array);
 static void json_free_pair(struct json_pair *pair);
 static void json_free_value(struct json_value *value);
+
 void json_free_object(struct json_object *obj)
 {
 	int i;
diff --git a/stat.c b/stat.c
index 4d3e974..2665952 100644
--- a/stat.c
+++ b/stat.c
@@ -852,7 +852,7 @@
 	int i;
 
 	/* General Info */
-	log_info("%s;%s;%s;%d;%d", ver, fio_version_string,
+	log_info("%d;%s;%s;%d;%d", ver, fio_version_string,
 					ts->name, ts->groupid, ts->error);
 	/* Log Read Status */
 	show_ddir_status_terse(ts, rs, DDIR_READ);
@@ -924,7 +924,7 @@
 
 	add_ddir_status_json(ts, rs, DDIR_READ, root);
 	add_ddir_status_json(ts, rs, DDIR_WRITE, root);
-//	add_ddir_status_json(ts, rs, DDIR_TRIM, root);
+	add_ddir_status_json(ts, rs, DDIR_TRIM, root);
 
 	/* CPU Usage */
 	if (ts->total_run_time) {
@@ -1280,10 +1280,9 @@
 	/*
 	 * don't overwrite last signal output
 	 */
-	if (!terse_output)
+	if (output_format == FIO_OUTPUT_NORMAL)
 		log_info("\n");
-
-	if (terse_output && terse_version == 4) {
+	else if (output_format == FIO_OUTPUT_JSON) {
 		root = json_create_object();
 		json_object_add_value_string(root, "fio version", fio_version_string);
 		array = json_create_array();
@@ -1296,18 +1295,15 @@
 
 		if (is_backend)
 			fio_server_send_ts(ts, rs);
-		else if (terse_output) {
-			if (terse_version != 4)
-				show_thread_status_terse(ts, rs);
-			else {
-				struct json_object *tmp = show_thread_status_json(ts,
-					rs);
-				json_array_add_value_object(array, tmp);
-			}
+		else if (output_format == FIO_OUTPUT_TERSE)
+			show_thread_status_terse(ts, rs);
+		else if (output_format == FIO_OUTPUT_JSON) {
+			struct json_object *tmp = show_thread_status_json(ts, rs);
+			json_array_add_value_object(array, tmp);
 		} else
 			show_thread_status(ts, rs);
 	}
-	if (terse_output && terse_version == 4) {
+	if (output_format == FIO_OUTPUT_JSON) {
 		/* disk util stats, if any */
 		show_disk_util(1, root);
 
@@ -1322,13 +1318,13 @@
 		rs->groupid = i;
 		if (is_backend)
 			fio_server_send_gs(rs);
-		else if (!terse_output)
+		else if (output_format == FIO_OUTPUT_NORMAL)
 			show_group_stats(rs);
 	}
 
 	if (is_backend)
 		fio_server_send_du();
-	else if (!terse_output)
+	else if (output_format == FIO_OUTPUT_NORMAL)
 		show_disk_util(0, NULL);
 
 	free(runstats);