From eaa60253fbe128d7cc02efba9f6b9450f8ae1fa6 Mon Sep 17 00:00:00 2001
From: Etienne Brateau <etienne.brateau@gmail.com>
Date: Sun, 20 Oct 2019 16:00:05 +0200
Subject: [PATCH] privatize trace variables and rename functions to be more
 readable

---
 Makefile               |  2 +-
 include/log_action.h   |  4 --
 include/logglobals.h   |  3 +-
 include/utils/logger.h | 40 ++++++++++++++++--
 src/ana/globals.c      |  8 ++--
 src/gate.c             |  8 ++--
 src/log.c              | 93 ++++++++++++------------------------------
 src/loged.c            |  6 +--
 src/logsim.c           |  5 ++-
 src/node.c             | 90 ++++++++++++++++++++--------------------
 src/pagewriter.c       |  3 +-
 src/tool.c             |  6 +--
 src/utils/logger.c     | 85 +++++++++++++++++++++++++++++++-------
 src/wire.c             | 28 ++++++-------
 14 files changed, 214 insertions(+), 167 deletions(-)

diff --git a/Makefile b/Makefile
index 8dfaf00..3421040 100644
--- a/Makefile
+++ b/Makefile
@@ -81,6 +81,7 @@ UTILSOBJ = $(TARGET_DIR)/utils/sysdevs.o \
 		$(TARGET_DIR)/utils/newasm.o \
 		$(TARGET_DIR)/utils/regex.o \
 		$(TARGET_DIR)/utils/p2c.o \
+		$(TARGET_DIR)/utils/logger.o \
 
 P2CLIBSTUFF = $(SRC_DIR)/lib/texstuff.ps $(SRC_DIR)/lib/untilstuff.ps $(SRC_DIR)/lib/plot.font
 
@@ -121,7 +122,6 @@ TOOLOBJ = $(SIMOBJ) \
 	  $(TARGET_DIR)/keyboard.o $(TARGET_DIR)/box.o \
 	  $(TARGET_DIR)/pen.o $(TARGET_DIR)/libraryreader.o \
 	  $(TARGET_DIR)/display.o \
-	  $(TARGET_DIR)/utils/logger.o \
 
 
 $(TARGET_DIR)/ana/%.o: $(SRC_DIR)/ana/%.c
diff --git a/include/log_action.h b/include/log_action.h
index 3284a84..83da49b 100644
--- a/include/log_action.h
+++ b/include/log_action.h
@@ -266,9 +266,7 @@ typedef struct log_action_t
 
 	int histactive;      /** Scope mode is triggered */
 	int dumpopen;        /** Dump output file is open */
-	int traceopen;       /** Trace output is open */
 	int verbose;         /** Commands acknowledge with messages */
-	int traceflag;       /** Debuggin/trace mode on */
 	int quiet;           /** Suppress sound signals */
 	int glowmode;        /** Glowing-wires mode */
 	int probemode;       /** Probe-cursor mode */
@@ -308,8 +306,6 @@ typedef struct log_action_t
 	short cy_max;
 	/** Area covered bu cyrsor */
 
-	FILE **tracefile;
-
 	char *homedirname;
 
 	struct log_tool *toolbase;
diff --git a/include/logglobals.h b/include/logglobals.h
index b5810ed..b84da2c 100644
--- a/include/logglobals.h
+++ b/include/logglobals.h
@@ -142,8 +142,7 @@ extern char *librgroupnames[9];
 
 extern short refrtimer, refrtimer0;   /* Time until screen is refreshed */
 
-extern char *dumpfname, *tracefname;
-extern FILE *tracefile;
+extern char *dumpfname;
 
 extern char pushedbackkey, realkey;
 
diff --git a/include/utils/logger.h b/include/utils/logger.h
index 84d6b12..47c57bd 100644
--- a/include/utils/logger.h
+++ b/include/utils/logger.h
@@ -1,16 +1,48 @@
 #ifndef LOGGER_H
 #define LOGGER_H
 #include <stdarg.h>
+#include <utils/p2c.h>
 
 
 /**
- * Write the message passed in parameter in the tracefile
+ * Write the message passed in parameter in the trace file
  */
-void vtracemessage(char *fmt, va_list ap);
+void vtrace_message(char *fmt, va_list ap);
 
 /**
- * Write the message passed in parameter in the tracefile
+ * Write the message passed in parameter in the trace file
  */
-void tracemessage(char *fmt, ...);
+void trace_message(char *fmt, ...);
+
+/**
+ * Close the trace file
+ */
+void close_trace();
+
+/**
+ * Take the new name of the trace file and enable the trace
+ */
+void set_trace_name(char *name_);
+
+/**
+ * Initialize the trace
+ */
+void trace_init();
+
+/**
+ * enable or disable trace
+ */
+void trace_enable(int enable);
+
+/**
+ * return if the trace is enabled of not
+ */
+int is_trace_enabled();
+
+/**
+ * Return trace file
+ * DEPRECATED
+ */
+FILE *get_trace_file() DEPRECATED;
 
 #endif
diff --git a/src/ana/globals.c b/src/ana/globals.c
index 1fa9d0e..2ecf554 100644
--- a/src/ana/globals.c
+++ b/src/ana/globals.c
@@ -893,13 +893,13 @@ int *Ok;
 static void Dataout(data)
 char *data;
 {
-	tracemessage(data);
+	trace_message(data);
 }
 
 
 static void Linefeed()
 {
-	tracemessage("\n");
+	trace_message("\n");
 }
 
 
@@ -917,7 +917,7 @@ void AnaMatdump()
   long FORLIM, FORLIM1;
   AnaMatRec *WITH;
 
-  if (!istraceenabled())
+  if (!is_trace_enabled())
     return;
   Openfiles();
   sprintf(STR3, "Iteration # %ld Timestep %g", AnaItercount, AnaDt);
@@ -1023,7 +1023,7 @@ void AnaDiffdump()
   long FORLIM, FORLIM1;
   AnaMatRec *WITH;
 
-  if (!istraceenabled())
+  if (!is_trace_enabled())
     return;
   Openfiles();
   FORLIM = AnaSysRow;
diff --git a/src/gate.c b/src/gate.c
index a187525..ad97a32 100644
--- a/src/gate.c
+++ b/src/gate.c
@@ -311,7 +311,7 @@ void chggate(log_grec *gate, int i, log_nrec *oldnode, log_nrec *n)
 	log_grec *g1;
 	short j, k, savepg, pg, x, y, FORLIM;
 
-	tracemessage("Change gate %p pin %d to node %p\n", gate, i, n);
+	trace_message("Change gate %p pin %d to node %p\n", gate, i, n);
 	j = i;
 	do
 	{
@@ -383,7 +383,7 @@ void chggatepin(log_grec *gate, short i, log_nrec **oldnode, log_nrec **savenode
 	log_grec *g1;
 	short j, x, y, FORLIM;
 
-	tracemessage("Change gate %p pin %d from node %p\n", gate, i, *oldnode);
+	trace_message("Change gate %p pin %d from node %p\n", gate, i, *oldnode);
 	x = gate->pinpos[i - 1].x;
 	y = gate->pinpos[i - 1].y;
 	hw = gg.pages[gg.curpage - 1]->hwbase;
@@ -438,7 +438,7 @@ void disconnectgate(log_grec *gate)
 	long done[log_maxpins / 32 + 2];
 	short FORLIM;
 
-	tracemessage("Disconnect gate %p\n", gate);
+	trace_message("Disconnect gate %p\n", gate);
 	stamp(&gate->kind->simtype->netstamp);
 	calltoolgate(gate, act_disconnectgate);
 	oldnode = (log_nrec **)Malloc(gate->kind->numpins * sizeof(log_nrec *));
@@ -531,7 +531,7 @@ int connectgate(log_grec *gate)
 	int success;
 	short FORLIM, FORLIM1;
 
-	tracemessage("Connect gate %p, type %s\n", gate, gate->kind->name);
+	trace_message("Connect gate %p, type %s\n", gate, gate->kind->name);
 	linkgate(&gate);
 	initpinpos(gate);
 	FORLIM = gate->kind->numpins;
diff --git a/src/log.c b/src/log.c
index 769140a..0ec4971 100644
--- a/src/log.c
+++ b/src/log.c
@@ -225,9 +225,7 @@ short refrtimer;    ///< Time until screen is refreshed
 short refrtimer0;   ///< Time until screen is refreshed
 
 char *dumpfname;
-char *tracefname;
 FILE *dumpfile;
-FILE *tracefile;
 
 char pushedbackkey;
 char realkey;
@@ -284,7 +282,7 @@ void report(int num, char *s)
 	clearshowalpha();
 	nc_gotoXY(0, txdown - 1);
 	nc_printf("\215--> Internal error %d in %s\210\n", num, s);
-	tracemessage("--> Internal error %d in %s\n", num, s);
+	trace_message("--> Internal error %d in %s\n", num, s);
 	m_alpha_on();
 	nc_printf("    Press any key to continue.");
 	ch = m_inkey();
@@ -750,23 +748,6 @@ static void closedump()
 }
 
 
-static void closetrace()
-{
-	if (gg.traceopen)
-	{
-		TRY(try5);
-		if (tracefile != NULL)
-			fclose(tracefile);
-		tracefile = NULL;
-		RECOVER(try5);
-		if (P_escapecode == -20)
-			_Escape(P_escapecode);
-		ENDTRY(try5);
-	}
-	gg.traceopen = false;
-}
-
-
 static void setdumpname(char *name_)
 {
 	char name[256];
@@ -778,22 +759,10 @@ static void setdumpname(char *name_)
 }
 
 
-static void settracename(char *name_)
-{
-	char name[256];
-
-	strcpy(name, name_);
-	newci_fixfname(name, "text", "");
-	closetrace();
-	strcpy(tracefname, name);
-	tracemessage("Trace mode ON\n");
-}
-
-
 static void closedumpfiles()
 {
 	closedump();
-	closetrace();
+	close_trace();
 }
 
 
@@ -1412,7 +1381,7 @@ log_tool *findsimtype(uchar st)
 
 	sprintf(simname, "%d", st);
 	stp = findtool(simname);
-	tracemessage("Findsimtype of %d gets %p\n", st, stp);
+	trace_message("Findsimtype of %d gets %p\n", st, stp);
 	if (!stp->ready || !stp->simulator)
 	{
 		rdy = stp->ready;
@@ -2104,9 +2073,11 @@ void doimmedfunction()
 	}
 	if (!strcmp(gg.func, "TRACE"))
 	{
-		getbool(gg.funcarg, &gg.traceflag);
-		vmessageflag("Trace mode ", gg.traceflag);
-		tracemessage("Trace mode ON\n");
+		int boolvalue;
+		getbool(gg.funcarg, &boolvalue);
+		trace_enable(boolvalue);
+		vmessageflag("Trace mode ", is_trace_enabled());
+		trace_message("Trace mode ON\n");
 		clearfunc();
 		return;
 	}
@@ -2118,7 +2089,7 @@ void doimmedfunction()
 	}
 	if (!strcmp(gg.func, "TRACEFILE"))
 	{
-		settracename(gg.funcarg);
+		set_trace_name(gg.funcarg);
 		clearfunc();
 		return;
 	}
@@ -2263,7 +2234,7 @@ void confirmsimtype(log_nrec *n)
 	log_hnrec *hn;
 	short FORLIM, FORLIM1;
 
-	tracemessage("Confirm simtype of %ld\n", (long)n);
+	trace_message("Confirm simtype of %ld\n", (long)n);
 	if (n == NULL || n->simtype->simtype < 8)
 		return;
 	found = false;
@@ -2289,7 +2260,7 @@ void confirmsimtype(log_nrec *n)
 	if (found)
 		return;
 
-	tracemessage("Deleting simtype of %ld\n", (long)n);
+	trace_message("Deleting simtype of %ld\n", (long)n);
 	calltoolnode(n, act_disposenode);
 	disposeattrs(&n->attr, n->simtype->nnumattrs, n->simtype->nattr);
 	hn = gg.hnbase;
@@ -7545,7 +7516,7 @@ void histaddsignal(log_hnrec **hn, short sig, short y)
 	(*hn)->sig = sig;
 	tool = gg.signaltab[sig - 1].np->simtype;
 	newattrs(&(*hn)->attr, tool->hnumattrs, tool->hattr);
-	tracemessage("Histaddsignal: %ld, %d\n", (long)(*hn)->attr, tool->hnumattrs);
+	trace_message("Histaddsignal: %ld, %d\n", (long)(*hn)->attr, tool->hnumattrs);
 	(*hn)->next = gg.hnbase;
 	gg.hnbase = *hn;
 	reshuffle();
@@ -8755,7 +8726,7 @@ static void historycommand()
 
 								if (!flag)
 								{
-									tracemessage("Delete trace %ld\n", (long)hn);
+									trace_message("Delete trace %ld\n", (long)hn);
 									if (hn == histgridhn) {
 										histgridwhich = 0;
 										histgridhn = NULL;
@@ -9225,7 +9196,7 @@ if gg.t.y < 46 then y1 := 0; */
 		j = P_ioresult;
 		endbottom();
 		beginerror();
-		if (Debugging || debugprint || gg.traceflag)
+		if (Debugging || debugprint || is_trace_enabled())
 			nc_printf("%d/%d/%ld  ", i, j, EXCP_LINE);
 		if (i == -10 && (unsigned)j < 32 && ((1L << j) & 0x600) != 0)
 			nc_printf("Can't find file \"%s\"\n", filename);
@@ -9278,7 +9249,7 @@ static void readcommand()
 		j = P_ioresult;
 		endbottom();
 		beginerror();
-		if (Debugging || debugprint || gg.traceflag)
+		if (Debugging || debugprint || is_trace_enabled())
 			nc_printf("%ld/%ld/%ld  ", i, j, EXCP_LINE);
 
 		if (i == -10 && (unsigned long)j < 32 && ((1L << j) & 0x600) != 0)
@@ -9553,7 +9524,7 @@ static void status_log()
 		nc_printf("       Markers %s\n", onoff(STR2, gg.markers));
 		nc_printf("   Quiet mode %s", onoff(STR2, gg.quiet));
 		nc_printf("         Verbose mode %s", onoff(STR2, gg.verbose));
-		nc_printf("       Trace mode %s\n", onoff(STR2, gg.traceflag));
+		nc_printf("       Trace mode %s\n", onoff(STR2, is_trace_enabled()));
 		nc_gotoXY(0, txdown - 3);
 		nc_printf("Use the arrow keys to view status pages.  Press the space bar to quit.\n");
 		status_oldtime = -1.0;
@@ -11082,7 +11053,7 @@ static void inithooks()
 	gg.hook.message = message;
 	gg.hook.vmessage = vmessage;
 	gg.hook.vmessageflag = vmessageflag;
-	gg.hook.trace = tracemessage;
+	gg.hook.trace = trace_message;
 	gg.hook.dump = dumpmessage;
 	gg.hook.setdump = setdumpname;
 	gg.hook.closefiles = closedumpfiles;
@@ -11306,21 +11277,15 @@ static void initialize()
 	gg.dumpopen = false;
 	dumpfname = (char *)Malloc(256);
 	*dumpfname = '\0';
-	gg.traceopen = false;
-	gg.tracefile = &tracefile;
-	tracefname = (char *)Malloc(256);
-	*tracefname = '\0';
+	trace_init();
 
 	if (swtab[3].used > 0)
 		strcpy(dumpfname, swtab[3].UU.s);
 	if (swtab[4].used > 0)
-		strcpy(tracefname, swtab[4].UU.s);
+		set_trace_name(swtab[4].UU.s);
 	else if (swtab[2].used > 0)
-		strcpy(tracefname, swtab[2].UU.s);
-	if (*tracefname != '\0')
-		newci_fixfname(tracefname, "text", "");
-	gg.traceflag = (swtab[2].used > 0);
-	tracemessage("Trace mode ON\n");
+		set_trace_name(swtab[2].UU.s);
+	trace_enable(swtab[2].used > 0);
 	gg.homedirname = (char *)Malloc(256);
 
 	if (swtab[5].used > 0)
@@ -11764,10 +11729,8 @@ int main(int argc, char * argv[])
 	nc_text_in_window = 1;
 	PASCAL_MAIN(argc, argv);
 	srand(time(NULL));
-	tracefile = NULL;
 	dumpfile = NULL;
 	gg.initdone = false;
-	gg.traceopen = false;
 	gg.dumpopen = false;
 	excpline = -1;
 
@@ -12095,12 +12058,12 @@ int main(int argc, char * argv[])
 			if (tempch == 'y' || tempch == 'Y')
 			{
 				TRY(try43);
-				gg.traceflag = true;
-				tracemessage("\n");
-				tracemessage("ESCAPECODE %ld\n", temp2);
-				tracemessage("IORESULT   %ld\n", temp1);
-				tracemessage("LINE       %ld\n\n", excpline);
-				tracemessage("Current page: %ld\n", gg.curpage);
+				trace_enable(true);
+				trace_message("\n");
+				trace_message("ESCAPECODE %ld\n", temp2);
+				trace_message("IORESULT   %ld\n", temp1);
+				trace_message("LINE       %ld\n\n", excpline);
+				trace_message("Current page: %ld\n", gg.curpage);
 				dumpnodes();
 				RECOVER(try43);
 				nc_printf("Debugging printout failed.\n");
@@ -12135,8 +12098,6 @@ int main(int argc, char * argv[])
 	cleanlog();
 	if (dumpfile != NULL)
 		fclose(dumpfile);
-	if (tracefile != NULL)
-		fclose(tracefile);
 	exit(0);
 }
 
diff --git a/src/loged.c b/src/loged.c
index ef62bb5..1d2b163 100644
--- a/src/loged.c
+++ b/src/loged.c
@@ -46,9 +46,10 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 */
 #define SIM_KIND
 #include <unistd.h>
-#include <utils/p2c.h>
 #include <time.h>
 #include <stdlib.h>
+#include <utils/p2c.h>
+#include <utils/logger.h>
 
 
 #include "logdef.h"
@@ -6726,8 +6727,7 @@ int main(int argc, char * argv[])
   newsimtype = 0;
   firstpin = 1;
   initscreen();
-  gg.traceflag = false;
-  gg.traceopen = false;
+  trace_init();
   gg.dumpopen = false;
   gg.verbose = false;
   gg.quiet = true;
diff --git a/src/logsim.c b/src/logsim.c
index 65111e7..a7240e2 100644
--- a/src/logsim.c
+++ b/src/logsim.c
@@ -35,8 +35,9 @@
    */
 
 
-#include <utils/p2c.h>
 #include <stdlib.h>
+#include <utils/p2c.h>
+#include <utils/logger.h>
 #include "log_action.h"
 #include "logsim.h"
 #include "logsima.h"
@@ -1491,7 +1492,7 @@ void Log_16_proc(log_action_t *lact)
 	short FORLIM;
 
 	logsima_action.lact = lact;
-	if (lact->traceflag && traceactions && ((unsigned long)lact->action >= 32 ||
+	if (is_trace_enabled() && traceactions && ((unsigned long)lact->action >= 32 ||
 				((1L << ((long)lact->action)) &
 				 ((1L << ((long)act_pass)) | (1L << ((long)act_tstep)))) == 0))
 	{
diff --git a/src/node.c b/src/node.c
index bfc248b..f579f4e 100644
--- a/src/node.c
+++ b/src/node.c
@@ -33,7 +33,7 @@ void newnode(log_nrec **node, uchar st)
 	calltoolnode(*node, act_newnode);
 	(*node)->next = gg.nbase;
 	gg.nbase = *node;
-	tracemessage("Make node %p\n", *node);
+	trace_message("Make node %p\n", *node);
 }
 
 /// Create a new node, copied from another.
@@ -53,7 +53,7 @@ void copynode(log_nrec *old, log_nrec **node)
 		(*node)->confnext = nodeconflictbase;
 		nodeconflictbase = *node;
 	}
-	tracemessage("Copy node %p from %p\n", *node, old);
+	trace_message("Copy node %p from %p\n", *node, old);
 }
 
 
@@ -72,7 +72,7 @@ void disposenode(log_nrec **node)
 {
 	log_nrec *n1, *n2;
 
-	tracemessage("Dispose node %p\n", *node);
+	trace_message("Dispose node %p\n", *node);
 	if (*node == NULL)
 		return;
 	if ((*node)->conflict || (*node)->oconflict)
@@ -139,7 +139,7 @@ log_nrec *refnode(log_nrec *node)
 	if (node == NULL)
 		return node;
 	node->ref++;
-	tracemessage("Reference node %p -> %d\n", node, node->ref);
+	trace_message("Reference node %p -> %d\n", node, node->ref);
 	return node;
 }
 
@@ -152,7 +152,7 @@ void unrefnode(log_nrec **node)
 	if (*node == NULL)
 		return;
 	(*node)->ref--;
-	tracemessage("Unref node %p -> %d\n", *node, (*node)->ref);
+	trace_message("Unref node %p -> %d\n", *node, (*node)->ref);
 	if ((*node)->ref > 0)
 		return;
 	if ((*node)->ref < 0)
@@ -192,36 +192,36 @@ void dumpnodes()
 	short FORLIM;
 	log_krec *WITH;
 
-	tracemessage("\n");
+	trace_message("\n");
 	sysdate(&datevar);
 	systime(&timevar);
-	tracemessage("--------------------------------------------------------  ");
-	tracemessage("%2d/%2d/%02d", datevar.month, datevar.day, datevar.year);
-	tracemessage("  %2d:%2d\n\n", timevar.hour, timevar.minute);
+	trace_message("--------------------------------------------------------  ");
+	trace_message("%2d/%2d/%02d", datevar.month, datevar.day, datevar.year);
+	trace_message("  %2d:%2d\n\n", timevar.hour, timevar.minute);
 	n = gg.nbase;
-	tracemessage("NODES\n");
+	trace_message("NODES\n");
 	i = 0;
 	j = 0;
 	TRY(try6);
 	while (j == i && n != NULL)
 	{
 		i++;
-		tracemessage("%p  T:%s  Ref:%d", n, n->simtype->name, n->ref);
+		trace_message("%p  T:%s  Ref:%d", n, n->simtype->name, n->ref);
 		FORLIM = gg.lastsignal;
 		for (j = 0; j < FORLIM; j++)
 		{
 			if (gg.signaltab[j].np == n)
-				tracemessage("   %s", gg.signaltab[j].name);
+				trace_message("   %s", gg.signaltab[j].name);
 		}
-		tracemessage("\n");
+		trace_message("\n");
 		TRY(try7);
-		gg.actfile = gg.tracefile;
+		gg.actfile = get_trace_file();
 		gg.actflag = true;
 		calltoolnode(n, act_writenode);
 		RECOVER(try7);
 		if (P_escapecode == -20)
 			goto _Ltry6;
-		tracemessage("  (Failed to output node value)   %d\n", P_escapecode);
+		trace_message("  (Failed to output node value)   %d\n", P_escapecode);
 		ENDTRY(try7);
 		n1 = gg.nbase;
 		j = 1;
@@ -231,21 +231,21 @@ void dumpnodes()
 			n1 = n1->next;
 		}
 		if (j < i)
-			tracemessage("Infinite loop in node list\n");
+			trace_message("Infinite loop in node list\n");
 		n = n->next;
 	}
 	RECOVER2(try6,_Ltry6);
 	if (P_escapecode == -20)
 		_Escape(P_escapecode);
-	tracemessage("  Internal error, %d\n", P_escapecode);
+	trace_message("  Internal error, %d\n", P_escapecode);
 	ENDTRY(try6);
-	tracemessage("\n");
+	trace_message("\n");
 	hw = gg.pages[gg.curpage - 1]->hwbase;
-	tracemessage("HWIRES\n");
+	trace_message("HWIRES\n");
 	TRY(try8);
 	while (hw != NULL)
 	{
-		tracemessage("%p  X1:%4d X2:%4d  Y:%4d  N:%p  C:%s\n",
+		trace_message("%p  X1:%4d X2:%4d  Y:%4d  N:%p  C:%s\n",
 				hw, hw->x1, hw->x2, hw->y, hw->node,
 				colorname(STR3, hw->wcolr));
 		hw = hw->next;
@@ -253,15 +253,15 @@ void dumpnodes()
 	RECOVER(try8);
 	if (P_escapecode == -20)
 		_Escape(P_escapecode);
-	tracemessage("  Internal error, %d\n", P_escapecode);
+	trace_message("  Internal error, %d\n", P_escapecode);
 	ENDTRY(try8);
-	tracemessage("\n");
+	trace_message("\n");
 	vw = gg.pages[gg.curpage - 1]->vwbase;
-	tracemessage("VWIRES\n");
+	trace_message("VWIRES\n");
 	TRY(try9);
 	while (vw != NULL)
 	{
-		tracemessage( "%p   X:%4d Y1:%4d Y2:%4d  N:%p  C:%s\n",
+		trace_message( "%p   X:%4d Y1:%4d Y2:%4d  N:%p  C:%s\n",
 				vw, vw->x, vw->y1, vw->y2, vw->node,
 				colorname(STR3, vw->wcolr));
 		vw = vw->next;
@@ -269,66 +269,66 @@ void dumpnodes()
 	RECOVER(try9);
 	if (P_escapecode == -20)
 		_Escape(P_escapecode);
-	tracemessage("  Internal error, %d\n", P_escapecode);
+	trace_message("  Internal error, %d\n", P_escapecode);
 	ENDTRY(try9);
-	tracemessage("\n");
+	trace_message("\n");
 	s = gg.pages[gg.curpage - 1]->sbase;
-	tracemessage("SOLDER\n");
+	trace_message("SOLDER\n");
 	TRY(try10);
 	while (s != NULL)
 	{
-		tracemessage("%p   X:%4d  Y:%4d    HW: %p,%p",
+		trace_message("%p   X:%4d  Y:%4d    HW: %p,%p",
 				s, s->x, s->y, s->hwire, s->hwire2);
 		if (s->hwire == NULL)
-			tracemessage("      ");
-		tracemessage("    VW: %p,%p\n", s->vwire, s->vwire2);
+			trace_message("      ");
+		trace_message("    VW: %p,%p\n", s->vwire, s->vwire2);
 		s = s->next;
 	}
 	RECOVER(try10);
 	if (P_escapecode == -20)
 		_Escape(P_escapecode);
-	tracemessage("  Internal error, %d\n", P_escapecode);
+	trace_message("  Internal error, %d\n", P_escapecode);
 	ENDTRY(try10);
-	tracemessage("\n");
+	trace_message("\n");
 	g = gg.pages[gg.curpage - 1]->gbase;
-	tracemessage("GATES\n");
+	trace_message("GATES\n");
 	TRY(try11);
 	while (g != NULL)
 	{
-		tracemessage("%p  G:%3d    X:%4d  Y:%4d  T:%s        %s\n",
+		trace_message("%p  G:%3d    X:%4d  Y:%4d  T:%s        %s\n",
 				g, g->g, g->x, g->y, g->kind->simtype->name,
 				g->kind->name);
 		WITH = g->kind;
 		FORLIM = WITH->numpins;
 		for (i = 0; i < FORLIM; i++)
 		{
-			tracemessage("              Pin %2d   X:%4d  Y:%4d  N:%p",
+			trace_message("              Pin %2d   X:%4d  Y:%4d  N:%p",
 					i + 1, g->pinpos[i].x, g->pinpos[i].y, g->pin[i]);
 			TRY(try12);
-			tracemessage(" [%d]", g->pin[i]->ref);
+			trace_message(" [%d]", g->pin[i]->ref);
 			RECOVER(try12);
 			if (P_escapecode == -20)
 				goto _Ltry11;
 			ENDTRY(try12);
-			tracemessage("\n");
+			trace_message("\n");
 		}
 		TRY(try13);
-		gg.actfile = gg.tracefile;
+		gg.actfile = get_trace_file();
 		gg.actflag = true;
 		calltoolgate(g, act_writegate);
 		RECOVER(try13);
 		if (P_escapecode == -20)
 			goto _Ltry11;
-		tracemessage("  (Failed to output gate value)   %d\n", P_escapecode);
+		trace_message("  (Failed to output gate value)   %d\n", P_escapecode);
 		ENDTRY(try13);
 		g = g->next;
 	}
 	RECOVER2(try11,_Ltry11);
 	if (P_escapecode == -20)
 		_Escape(P_escapecode);
-	tracemessage("  Internal error, %d\n", P_escapecode);
+	trace_message("  Internal error, %d\n", P_escapecode);
 	ENDTRY(try11);
-	tracemessage("\n\n-------------------------------------------------------------------------\n\n\n");
+	trace_message("\n\n-------------------------------------------------------------------------\n\n\n");
 }
 
 void delgetnode(log_nrec **save, log_nrec **old, log_nrec **node)
@@ -351,7 +351,7 @@ void combinenodes(log_nrec **n2, log_nrec **n1, cnrec *cnbase)
 	log_tool *oldsimtype, *newsimtype;
 	short i, pg, FORLIM, FORLIM1;
 
-	tracemessage("Combine node %ld into %ld\n", (long)(*n1), (long)(*n2));
+	trace_message("Combine node %ld into %ld\n", (long)(*n1), (long)(*n2));
 	if (*n2 == NULL)
 		switchnode(n2, *n1);
 	nn1 = *n1;   /*VAR params may change out from under us*/
@@ -469,7 +469,7 @@ void queuecombine(cnrec **cnbase, log_nrec **n, log_nrec **n2)
 {
 	cnrec *cn;
 
-	tracemessage("Queue-combine,  n = %ld,  np -> %ld\n", (long)(*n), (long)(*n2));
+	trace_message("Queue-combine,  n = %ld,  np -> %ld\n", (long)(*n), (long)(*n2));
 	if (*n == NULL)
 		return;
 	cn = (cnrec *)Malloc(sizeof(cnrec));
@@ -544,8 +544,8 @@ int checkcombine(cnrec **cnbase_)
                         }
                 }
 
-				if (gg.traceflag && *V.cnbase != NULL)
-					tracemessage("Check-combine (pass %d) finds %s\n",
+				if (*V.cnbase != NULL)
+					trace_message("Check-combine (pass %d) finds %s\n",
                                         V.passcount, V.good ? " TRUE" : "FALSE");
                 V.passcount++;
         } while (!(V.good || V.passcount > 2));
diff --git a/src/pagewriter.c b/src/pagewriter.c
index 4ad95a0..669fa99 100644
--- a/src/pagewriter.c
+++ b/src/pagewriter.c
@@ -2,6 +2,7 @@
 
 #include "logfont.h"
 #include <utils/filepack.h>
+#include <utils/logger.h>
 #include <graphics/newcrt.h>
 #include <graphics/newci.h>
 #include "log.h"
@@ -538,7 +539,7 @@ void safesavepage(short pgnum, char *fn)
 	j = P_ioresult;
 	endbottom();
 	beginerror();
-	if (Debugging || debugprint || gg.traceflag)
+	if (Debugging || debugprint || istraceenabled())
 		nc_printf("%ld/%ld/%ld   ", i, j, EXCP_LINE);
 	nc_printf("Unable to save file %s\n", fn);
 	enderror();
diff --git a/src/tool.c b/src/tool.c
index b50b15e..b2884d0 100644
--- a/src/tool.c
+++ b/src/tool.c
@@ -64,20 +64,20 @@ log_tool *findtool(char *name_)
 	{
 		sprintf(suffix, "LOG_%s_PROC", name);
 		ready = findprocedure(suffix, (void(**) ())(&proc));
-		tracemessage("Findtool to load: %s -  %s.\n", suffix, lp->fname);
+		trace_message("Findtool to load: %s -  %s.\n", suffix, lp->fname);
 
 		if (!ready && lp->fname != NULL)
 		{
 			TRY(try2);
 			newci_fixfname(lp->fname, "code", "");
-			tracemessage("Findtool, loading %s\n", lp->fname);
+			trace_message("Findtool, loading %s\n", lp->fname);
 			//newci_loadprogram(lp->fname); << do nothing
 			RECOVER(try2);
 			if (P_escapecode == -20)
 				_Escape(P_escapecode);
 			ENDTRY(try2);
 			ready = findprocedure(suffix, (void(**) ())(&proc));
-			tracemessage("Findtool, ready=%s\n", ready ? " TRUE" : "FALSE");
+			trace_message("Findtool, ready=%s\n", ready ? " TRUE" : "FALSE");
 		}
 
 		if (ready)
diff --git a/src/utils/logger.c b/src/utils/logger.c
index c293168..70b8bfa 100644
--- a/src/utils/logger.c
+++ b/src/utils/logger.c
@@ -1,39 +1,96 @@
 #include "utils/logger.h"
 #include "logglobals.h"
+#include <graphics/newci.h>
 
-void vtracemessage(char *fmt, va_list ap)
+FILE *trace_file;
+char *trace_fname;
+int trace_opened;       /** Trace output is open */
+int trace_enabled;       /** Debuggin/trace mode on */
+
+void vtrace_message(char *fmt, va_list ap)
 {
-	if (!gg.traceflag)
+	if (!trace_enabled)
 		return;
 
-	if (!gg.traceopen)
+	if (!trace_opened)
 	{
-		if (*tracefname == '\0')
+		if (*trace_fname == '\0')
 		{
 			do
 			{
-				sprintf(tracefname, "/tmp/%.10s%03ld",
+				sprintf(trace_fname, "/tmp/%.10s%03ld",
 						cuserid(NULL), rand() % 1000L);
 
-			} while (access(tracefname, F_OK) == 0);
+			} while (access(trace_fname, F_OK) == 0);
 		}
-		if (tracefile != NULL)
-			tracefile = freopen(tracefname, "a", tracefile);
+		if (trace_file != NULL)
+			trace_file = freopen(trace_fname, "a", trace_file);
 		else
-			tracefile = fopen(tracefname, "a");
-		if (tracefile == NULL)
+			trace_file = fopen(trace_fname, "a");
+		if (trace_file == NULL)
 			_EscIO(FileNotFound);
-		gg.traceopen = true;
+		trace_opened = true;
 	}
 	
-	vfprintf(tracefile, fmt, ap);
+	vfprintf(trace_file, fmt, ap);
 }
 
-void tracemessage(char *fmt, ...)
+void trace_message(char *fmt, ...)
 {
 
 	va_list ap;
 	va_start(ap, fmt);
-	vtracemessage(fmt, ap);
+	vtrace_message(fmt, ap);
 	va_end(ap);
 }
+
+void set_trace_name(char *name_)
+{
+	char name[256];
+
+	strcpy(name, name_);
+	if (*name != '\0')
+		newci_fixfname(name, "text", "");
+	close_trace();
+	strcpy(trace_fname, name);
+	trace_message("Trace mode ON\n");
+}
+
+void close_trace()
+{
+	if (trace_opened)
+	{
+		TRY(try5);
+		if (trace_file != NULL)
+			fclose(trace_file);
+		trace_file = NULL;
+		RECOVER(try5);
+		if (P_escapecode == -20)
+			_Escape(P_escapecode);
+		ENDTRY(try5);
+	}
+	trace_opened = false;
+}
+
+void trace_init()
+{
+	trace_fname = (char *) Malloc(2560);
+	*trace_fname = '\0';
+	trace_opened = false;
+}
+
+
+void trace_enable(int enable)
+{
+	trace_enabled = enable;
+}
+
+int is_trace_enabled()
+{
+	return trace_enabled;
+}
+
+FILE *get_trace_file()
+{
+	return trace_file;
+}
diff --git a/src/wire.c b/src/wire.c
index 9fb7097..49a42b1 100644
--- a/src/wire.c
+++ b/src/wire.c
@@ -99,7 +99,7 @@ void disphw(log_hwrec **hw)
 {
 	log_hwrec *hw1;
 
-	tracemessage("Dispose hwire %ld\n", (long)(*hw));
+	trace_message("Dispose hwire %ld\n", (long)(*hw));
 	if (*hw == NULL)
 		return;
 	hw1 = gg.pages[gg.curpage - 1]->hwbase;
@@ -141,7 +141,7 @@ void dispvw(log_vwrec **vw)
 {
 	log_vwrec *vw1;
 
-	tracemessage("Dispose vwire %ld\n", (long)(*vw));
+	trace_message("Dispose vwire %ld\n", (long)(*vw));
 	if (*vw == NULL)
 		return;
 	vw1 = gg.pages[gg.curpage - 1]->vwbase;
@@ -186,7 +186,7 @@ void dispsolder(log_srec **s)
 {
 	log_srec *s1;
 
-	tracemessage("Dispose solder %ld\n", (long)(*s));
+	trace_message("Dispose solder %ld\n", (long)(*s));
 	if (*s == NULL)
 		return;
 	s1 = gg.pages[gg.curpage - 1]->sbase;
@@ -295,7 +295,7 @@ void addsolder(short x, short y, log_hwrec *hw, log_hwrec *hw2, log_vwrec *vw, l
 		else
 			report(4, rtn);
 	}
-	tracemessage("Add solder %ld\n", (long)s);
+	trace_message("Add solder %ld\n", (long)s);
 }
 
 #undef rtn
@@ -349,7 +349,7 @@ void chghw(log_hwrec *hw, log_nrec *oldnode, log_nrec *n)
 	log_srec *s;
 	short i, px, FORLIM;
 
-	tracemessage("Change hwire %ld to node %ld\n", (long)hw, (long)n);
+	trace_message("Change hwire %ld to node %ld\n", (long)hw, (long)n);
 	switchnode(&hw->node, n);
 	g = gg.pages[gg.curpage - 1]->gbase;
 	while (g != NULL)
@@ -416,7 +416,7 @@ void chgvw(log_vwrec *vw, log_nrec *oldnode, log_nrec *n)
 	log_srec *s;
 	short i, py, FORLIM;
 
-	tracemessage("Change vwire %ld to node %ld\n", (long)vw, (long)n);
+	trace_message("Change vwire %ld to node %ld\n", (long)vw, (long)n);
 	switchnode(&vw->node, n);
 	g = gg.pages[gg.curpage - 1]->gbase;
 	while (g != NULL)
@@ -493,7 +493,7 @@ void delhwire(log_hwrec *hw)
 	log_grec *g;
 	short i, x, y, FORLIM;
 
-	tracemessage("Delete hwire %ld\n", (long)hw);
+	trace_message("Delete hwire %ld\n", (long)hw);
 	clipon();
 	m_color((long)gg.color.backgr);
 	hline(hw->x1, hw->x2, hw->y);
@@ -517,7 +517,7 @@ void delhwire(log_hwrec *hw)
 			}
 			else
 			{
-				tracemessage("DELHW keeping solder %ld\n", (long)s);
+				trace_message("DELHW keeping solder %ld\n", (long)s);
 			}
 		}
 		s = s1;
@@ -584,7 +584,7 @@ void delvwire(log_vwrec *vw)
 	log_grec *g;
 	short i, x, y, FORLIM;
 
-	tracemessage("Delete vwire %ld\n", (long)vw);
+	trace_message("Delete vwire %ld\n", (long)vw);
 	clipon();
 	m_color((long)gg.color.backgr);
 	vline(vw->x, vw->y1, vw->y2);
@@ -607,7 +607,7 @@ void delvwire(log_vwrec *vw)
 			}
 			else
 			{
-				tracemessage("DELVW keeping solder %ld\n", (long)s);
+				trace_message("DELVW keeping solder %ld\n", (long)s);
 			}
 		}
 		s = s1;
@@ -686,7 +686,7 @@ void addhwire(short x1, short x2, short y, short colr)
 	blobrec *blbase;
 	short FORLIM;
 
-	tracemessage("Add hwire %d-%d, %d\n", x1, x2, y);
+	trace_message("Add hwire %d-%d, %d\n", x1, x2, y);
 	sortshints(&x1, &x2);
 	cnbase = NULL;
 	remcursor();
@@ -797,7 +797,7 @@ void addhwire(short x1, short x2, short y, short colr)
 	gg.nearhw = hw;
 	clipoff();
 	refreshsoon();
-	tracemessage("Added hwire %ld\n", (long)hw);
+	trace_message("Added hwire %ld\n", (long)hw);
 _L1:
 	dispblobs(&blbase);
 
@@ -833,7 +833,7 @@ void addvwire(short x, short y1, short y2, short colr)
 	blobrec *blbase;
 	short FORLIM;
 
-	tracemessage("Add vwire %d, %d-%d\n", x, y1, y2);
+	trace_message("Add vwire %d, %d-%d\n", x, y1, y2);
 	sortshints(&y1, &y2);
 	cnbase = NULL;
 	remcursor();
@@ -945,7 +945,7 @@ void addvwire(short x, short y1, short y2, short colr)
 	gg.nearvw = vw;
 	clipoff();
 	refreshsoon();
-	tracemessage("Added vwire %ld\n", (long)vw);
+	trace_message("Added vwire %ld\n", (long)vw);
 _L1:
 	dispblobs(&blbase);
 
-- 
GitLab