diff --git a/src/diglog/log.d b/src/diglog/log.d
new file mode 100644
index 0000000000000000000000000000000000000000..3ca214a4c4f41aff2d5019951a3069b4d92bb222
--- /dev/null
+++ b/src/diglog/log.d
@@ -0,0 +1,535 @@
+module diglog.log;
+
+import diglog.log_action;
+import std.experimental.logger : log, logf;
+import std.stdio;
+import std.string;
+
+
+string[] confFileName;
+bool vanilla;
+string dumpFileName;
+string homeDirectoryName;
+string[] toolName;
+string[] displayName;
+
+LogAction gg;
+/// Library files
+//filerecfilerec[] libf1;
+
+enum usage = q{
+Usage:  LOG [ -v ] [ -c cnffile ] [-r toolname ] [ -x X_display_name ] [ -z [-t filename] ] [ file ]
+};
+
+enum maxgatesfiles = 15;
+
+struct LOC_initialize {
+	short j;
+	//strlist_t* loadgates, logmenu;
+	string cmdbuf;
+	//cnfrec* cnflast;
+}
+
+/** @brief Initialize all variables.
+  Read basic gates from library.
+  Clear catalog window.
+  Initialize global data structures.
+  */
+static void initialize()
+{
+	LOC_initialize V;
+	short curgate;
+	short[maxgatesfiles] gptr, ggroup, gsize;
+	char[maxgatesfiles][9] gname;
+	//strlist_t *l1;
+	//char[256] s;
+	int flag;
+
+	// initialize graphics
+	/* set display name id exists */
+	/+if (displayName != null)
+	{
+		m_set_display_name(displayName.toStringZ);
+	}
+	initwindow2();
+	initcolormap();
+	cursortype = normal;
+	oldcursortype = normal;
+	setscale(0);
+	curlistgroup = 0;
+	messagepos = topmessagepos;
+	resetmessages();
+	initmenus();+/
+
+	// Initialize gg
+
+	gg.homedirname = (homeDirectoryName != null) ? homeDirectoryName : "~/log";
+	/*gg.curstamp = 0;
+	gg.verbose = true;
+	gg.glowmode = false;
+	gg.probemode = false;
+	gg.textinvisible = false;
+	gg.pnuminvisible = true;
+	gg.invisible = false;
+	gg.pwrflag = true;
+	gg.busyflag = true;
+	gg.quiet = false;
+	gg.dotsvisible = true;
+	gg.showconflicts = false;
+	gg.actstr = null;
+	gg.maxsignal = defmaxsignal;
+	gg.singlestepcount = 0;
+	gg.dumpopen = false;
+	gg.traceopen = false;
+	gg.tracefile = &tracefile;
+	gg.funcarg = null;
+	gg.toolbase = null;
+	gg.simstate = simst_null;
+	gg.simstatetool = null;
+	gg.fastmin = deffastmin;
+	gg.fastmax = deffastmax;
+	gg.fastrate = deffastrate;
+	gg.fastspeed = gg.fastmin;*/
+	//inithooks(gg);
+
+	/*
+	stamp(&gg.labelstamp);
+	stamp(&gg.boxstamp);
+	stamp(&gg.msgstamp);
+	stamp(&gg.refrstamp);
+	stamp(&gg.nattrstamp);
+	stamp(&gg.gattrstamp);
+	stamp(&gg.sigstamp);
+	stamp(&gg.loadstamp);
+	stamp(&gg.colorstamp);
+	stamp(&gg.resetstamp);
+	stamp(&gg.markerstamp);
+	*/
+
+/+
+	pushedbackkey = '\0';
+	conflictenbl = true;
+	conflictstop = false;
+	tempverbose = false;
+	conflictdelay = 1;
+	anyconflicts = false;
+	snapflag = false;
+	glowsolder = true;
+	libptr = 0;
+	helpptr = 0;
+	steppingoff = false;
+	vlsi = false;
+	dumpfname = null;
+	tracefname = null;
+	cursorhide = false;
+	loghelpname = "loghelp";
+	lognewsname = "lognews";
+	strlist_init(&gatefilenames);
+	cnfbase = NULL;
+	colorbase = NULL;
+	librstrs = NULL;
+	commandlist = NULL;
+	thingstodo = NULL;
+	nexttodo = NULL;
+	messages = NULL;
+	flag = false;
++/
+
+/+
+	// initialize macros
+	macrobase = NULL;
+	initmacros();
++/
+
+	/*strlist_init(&histlbl);
+	strlist_append(&histlbl, "Scope mode");
+	strlist_append(&histlbl, "");
+	strlist_append(&histlbl, "VContinuous,On Reset,Triggered,Manual:Type of trigger:");
+	strlist_append(&histlbl, "Triggered;C(none):Trigger signal:");
+	strlist_append(&histlbl, "On Reset;OUs:Time to start trigger:");
+	strlist_append(&histlbl, "On Reset;OUs:Time to stop trigger:");
+	strlist_append(&histlbl, "VTrigger off,Simulation off:Action when memory full:");
+	strlist_append(&histlbl, "");
+	strlist_append(&histlbl, "Us:Minimum timestep:");
+	strlist_append(&histlbl, "Us:Maximum timestep:");
+	strlist_append(&histlbl, "I100000:Timestep memory limit:");
+	strlist_append(&histlbl, "I:Timestep memory size:");
+	strlist_append(&histlbl, "");
+	strlist_append(&histlbl, "BY:Align signal names?");
+	strlist_append(&histlbl, "");
+	strlist_append(&histlbl, "Us,0:Time at left edge:");
+	strlist_append(&histlbl, "Us:Current time:");
+	strlist_append(&histlbl, "");
+	strlist_append(&histlbl, "Us,100us:Seconds per division:");
+	strlist_append(&histlbl, "Us:Current timestep:");
+	parselabel(&histlbl, &histnumattrs, &histkattr);
+	newattrs(&histgattr, histnumattrs, histkattr);*/
+
+	// intilialize V
+	/+
+	strlist_init(&V.loadgates);
+	strlist_init(&V.logmenu);
+	V.cnflast = NULL;
+	+/
+
+	/*if (confFileName != null) {
+		readcnf(cnfname, &V);
+	}
+	*/
+
+	/+initcolors();
+	gg.color.curbaseline = gg.color.baseline;
+	gg.baselinecolor = gg.color.baseline;
+
+	newci_fixfname(loghelpname, "help", "");
+	newci_fixfname(lognewsname, "text", "");
+
+	displaynews = (*lognewsname != '\0');
++/
+
+	// if page provided in command line, prepare to load them
+	/*if (P_argc > 1)
+	{
+		sprintf(STR2, "LOAD %s", P_argv[1]);
+		strlist_append(&thingstodo, STR2);
+		FORLIM = P_argc;
+		for (i = 2; i < FORLIM; i++)
+		{
+			sprintf(STR3, "PAGE %d", i);
+			strlist_append(&thingstodo, STR3);
+			sprintf(STR3, "LOAD %s", P_argv[i]);
+			strlist_append(&thingstodo, STR3);
+		}
+		displaynews = false;
+	}*/
+/+
+	if (toolName.length > 0)
+	{
+		string tools = "TOOL " ~ toolName.join(" ");
+		/*strlist_append(&thingstodo, tools);
+		displaynews = false;
+		justonecommand = true;*/
+	}
+	else
+	{
+		//justonecommand = false;
+	}
+
+	//addgatesfile("log", &V);
+
+	idxsize = 0;
+	for (short k = 0; k < maxgatesfiles; k++)
+	{
+		*gname[k] = '\0';
+		if (gatefilenames != null) {
+			//TRY(try35);
+			gatesname[k] = gatefilenames[i];
+			///libf1[k] = (filerecfilerec *)Malloc(sizeof(filerecfilerec));
+			///libf1[k].f = null;
+			//newci_fixfname(gatesname[k], "gate", "");
+			flag = false;
+			//TRY(try36);
+			try{
+				/*if (libf1[k].f != null)
+					libf1[k].f = freopen(gatesname[k], "r", libf1[k].f);
+				else
+					libf1[k].f = fopen(gatesname[k], "r");
+
+
+				assert (libf1[k].f != null, "File not found");
+
+				//RESETBUF(libf1[k]->f, filerec);
+				flag = true;*/
+			}
+			catch (Exception e)
+			{
+				/*if (P_escapecode == -20)
+					goto _Ltry35;*/
+			}
+			//TRY(try37);
+			try {
+				/*auto path = GetChipmunkPath("LOGLIB", LOGLIB) ~ gatesname[k];
+				if (libf1[k].f != null)
+				{
+					libf1[k]->f = freopen(path, "r", libf1[k]->f);
+				}
+				else
+				{
+					libf1[k]->f = fopen(path, "r");
+				}
+				gatesname[k] =  path;
+				assert (libf1[k]->f != NULL, "File not found");
+				//RESETBUF(libf1[k]->f, filerec);
+				flag = true;*/
+			}
+			catch (Exception e)
+			{
+				/*RECOVER2(try37,_Ltry37);
+				if (P_escapecode == -20)
+					goto _Ltry35;
+				ENDTRY(try37);*/
+			}
+			//ENDTRY(try36);
+			if (flag)
+			{
+				/*if (libf1[k].f != NULL)
+					rewind(libf1[k].f);
+				else
+					libf1[k].f = tmpfile();
+				assert (libf1[k].f == null, "File not found");
+
+				SETUPBUF(libf1[k].f, filerec);
+				fseek(libf1[k].f, 0, 0);
+				SETUPBUF(libf1[k].f, filerec);
+				GET(libf1[k].f, filerec);
+				gsize[k] = getshortsw((char *)(&GETFBUF(libf1[k].f, filerec).b[4]));
+				idxsize += gsize[k];
+				libfstart[k] = GETFBUF(libf1[k].f, filerec).b[6] + 1;
+				gptr[k] = 0;*/
+			}
+		}
+		/*RECOVER2(try35,_Ltry35);
+		if (P_escapecode == -20)
+			_Escape(P_escapecode);
+		beginfatal();
+		nc_printf("Can't open gates file \"%s\"\n", gatesname[k]);
+		endfatal();
+		ENDTRY(try35);
+		*/
+	}
+	assert (idxsize != 0, "No gates files!");
+	///index_ = (char(*)[9])Malloc(idxsize * 10L);
+	///indexfile = (uchar *)Malloc(idxsize);
+	///indexoffset = (short *)Malloc(idxsize * sizeof(short));
+	///indexgroup = (uchar *)Malloc(idxsize);
+	///loadedgates = (uchar *)Malloc((idxsize + 9L) / 8);
+	/*for (short i = 0; i < idxsize; i++)
+		P_clrbits_B(loadedgates, i, 0, 3);
+	*/
+	/+curgate = 1;
+	do
+	{
+		short k = 0;
+		s = "\177";
+		for (short i = 0; i < maxgatesfiles; i++)
+		{
+			if (gatesname[i] != null && *gname[i] == '\0' && gptr[i] < gsize[i])
+			{
+				//TRY(try38);
+				/*gptr[i]++;
+				if ((gptr[i] & 31) == 0)
+					GET(libf1[i]->f, filerec);
+				gname[i] = "        ";
+				strmove(8, GETFBUF(libf1[i].f, filerec).ix[gptr[i] & 31], 1, gname[i], 1);
+				ggroup[i] = 0;
+				for (V.j = 1; V.j <= 8; V.j++)
+				{
+					if ((gname[i][V.j - 1] & (~127)) != 0)
+					{
+						ggroup[i] = V.j;
+						gname[i][V.j - 1] = cast(char)(cast(uchar)gname[i][V.j - 1] - 128);
+					}
+				}*/
+				//RECOVER(try38);
+				/*if (P_escapecode == -20)
+					_Escape(P_escapecode);
+				beginfatal();
+				nc_printf("Can't read gates file \"%s\"\n", gatesname[i]);
+				endfatal();
+				ENDTRY(try38);
+				*/
+			}
+			if (strcmp(gname[i], s) < 0 && *gname[i] != '\0')
+			{
+				strcpy(s, gname[i]);
+				k = i + 1;
+			}
+		}
+		indexfile[curgate - 1] = k;
+		indexoffset[curgate - 1] = gptr[k - 1];
+		indexgroup[curgate - 1] = ggroup[k - 1];
+		strcpy(index_[curgate - 1], strrtrim(strcpy(STR3, s)));
+		for (i = 1; i <= maxgatesfiles; i++)
+		{
+			if (!strcmp(gname[i - 1], s))
+			{
+				*gname[i - 1] = '\0';
+				if (i != k)
+					idxsize--;
+			}
+		}
+		curgate++;
+	} while (curgate <= idxsize);+/
+	/+if (m_across >= 1023)
+	{
+		maxkinds = P_imin2(280L, cast(long)maxmaxkinds);
+		catwidth = 20;
+	}
+	else
+	{
+		maxkinds = P_imin2(70L, cast(long)maxmaxkinds);
+		catwidth = 10;
+	}+/
+	/+catboxes = null;
+	for (auto i = 0; i < maxkinds; i++)
+		kind[i] = null;
+	m_graphics_on();
+	clearalpha();+/
+
+	/+for(short i = 0; i < log_maxpages; ++i)
+		gg.pages[i] = pageAlloc();
+	gg.numpages = 1;
+	gg.curpage = 1;
+	gg.showpage = 1;
+	realcurpage = 1;
+	+/
+	/+setvlsimode(vlsi);
+	XRebindKeysym(m_display, XStringToKeysym("BackSpace"), null, 0, cast(unsigned char * )"\007", 1);
+	gg.refrflag = true;
+	gg.markers = false;
+	*gg.func = '\0';
+	*gg.genfunc = '\0';
+	gg.xoff = origin;
+	gg.yoff = origin;
+	xoffp[0] = origin;
+	yoffp[0] = origin;
+	xoff0 = 0;
+	yoff0 = 0;
+	gatecount[0] = 0;
+	gg.nbase = null;
+	stamp(&gg.pages[0].pagestamp);
+	curfilename[0] = null;
+	initbuf(&copybuf);
+	nodeconflictbase = null;
+	gateconflictbase = null;
+	gg.movinghw = null;
+	gg.movingvw = null;
+	gg.signaltab = cast(log_sigrec *)malloc(gg.maxsignal * sizeof(log_sigrec));
+	for (short i = 0; i < gg.maxsignal; i++)
+	{
+		auto signal = &gg.signaltab[i];
+		signal.name = null;
+		signal.np = null;
+	}
+	gg.lastsignal = 0;
+	gg.hnbase = null;
+	hncount = 0;
+	hnocount = 0;
+	gg.htbase = null;
+	gg.htlast = null;
+	htcount = 0;
+	histtrig = 0;
+	gg.histactive = false;
+	histonscreen = false;
+	histgridmode = 2;
+	histgridwhich = 0;
+	histgridhn = null;
+	gg.probenode = null;
+	gg.probegate = null;
+	gg.probepin = 0;
+	gg.probesimtype = null;
+	gg.probekind = null;
+	probeflag = false;
+	briefprobe = false;
+	firsttraining = true;
+	training = false;
+	cureditmode = 1;
+	*modename = '\0';
+	modeflag = false;
+	modetime = 0;
+	modeprobekind = null;
+	gg.time = 0.0;
+	gg.prevtimestep = 0.0;
+	reportnowait = false;
+	gg.startpoint = false;
+	simtype_ignore = findtool("0");
+	if (!simtype_ignore.ready)
+		report(10, rtn);
+	simtype_common = findtool("1");
+	if (!simtype_common.ready)
+		report(11, rtn);
+	short i = 1;
+	l1 = V.loadgates;
+	while (l1 != null && i != 0)
+	{
+		if (*l1.s == '\0')
+			getgategroup(cast(strlist_t *)l1.value);
+		else
+			i = readlibrary(l1.s);
+		l1 = l1.next;
+	}
+	strlist_empty(&V.loadgates);
+	l1 = V.logmenu;
+	for (short i = 0; i < kindgroupsize; i++)
+	{
+		kindgroup[i] = 0;
+		kindsig[i] = 0;
+		kindattr[i] = NULL;
+		if (l1 != NULL)
+		{
+			kindgroup[i] = readlibrary(l1.s);
+			l1 = l1.next;
+		}
+	}
+	strlist_empty(&V.logmenu);
+	refrwindow();
+	clearalpha();
+	+/
++/
+}
+
+int main(string[] args) {
+	import std.getopt;
+	import std.experimental.logger;
+
+	bool trace;
+	string traceFileName;
+
+	GetoptResult helpInformation;
+	try {
+		helpInformation = getopt(
+		args,
+		config.stopOnFirstNonOption,
+		"c", &confFileName,
+		"v", &vanilla,
+		"z", "Enable traces", &trace,
+		"d", &dumpFileName,
+		"t", "Location of trace file", &traceFileName,
+		"h", &homeDirectoryName,
+		"r", &toolName,
+		"x", &displayName);
+	}
+	catch (GetOptException e) {
+		writeln("%s\n", e.message);
+		writeln(usage);
+		return 1;
+	}
+
+	/* handle other arguments */
+	if (helpInformation.helpWanted)
+	{
+		writeln(usage);
+		defaultGetoptPrinter("Some information about the program.",
+		helpInformation.options);
+		return 0;
+	}
+
+	// Setup the loggers
+	auto logger = new MultiLogger();
+	auto defaultLog = sharedLog();
+	logger.insertLogger("default", sharedLog());
+	sharedLog(logger);
+	if (trace) {
+		if (traceFileName == null)
+			traceFileName = "/tmp/diglog.log";
+		log("Trace mode ON");
+		logger.insertLogger("trace", new FileLogger(traceFileName));
+		scope(exit) {
+			defaultLog.logf("Trace written to %s", traceFileName);
+		}
+	}
+
+	initialize();
+	//return program(cast(int) args.length, cast(char**) args.ptr);
+	return 0;
+}
diff --git a/src/diglog/log_action.d b/src/diglog/log_action.d
new file mode 100644
index 0000000000000000000000000000000000000000..60fd995b75c585f90010d1e73067d53286b42a86
--- /dev/null
+++ b/src/diglog/log_action.d
@@ -0,0 +1,152 @@
+module diglog.log_action;
+
+struct LogAction
+{
+    /*log_actionkinds action;
+    log_krec *actkind;
+    log_grec *actgate;
+    log_grec *actgate2;
+    log_nrec *actnode;
+    log_nrec *actnode2;*/
+    long actx;
+    long acty;
+    int actflag;
+    int actflag2;
+    //FILE **actfile;
+    //log_tool *acttool;
+    string actstr;
+    double actval;
+    double actval2;
+    double actval3;
+    //log_gattrrec *actgattr;
+    //log_kattrrec *actkattr;
+    char *actproc;
+
+    /*log_page[log_maxpages] *pages;
+    size_t numpages; ///< number of pages
+    log_nrec *nbase;
+    long curpage;  ///< current page number
+    long showpage; ///< currenctly displayed page number*/
+
+
+    //log_sigrec *signaltab;
+    short maxsignal;
+    short lastsignal;
+
+    short scale;
+    short hscale;
+    long xoff;	   ///< screen_x = grid_x * scale - xoff
+    long yoff;
+
+    char[17] func;
+    char *funcarg;
+
+    /*log_grec *neargate;
+    log_lrec *nearlabel;
+    log_brec *nearbox;
+    log_hwrec *nearhw;
+    log_hwrec *movinghw;
+    log_vwrec *nearvw;
+    log_vwrec *movingvw;
+
+    log_nrec *probenode;
+    log_grec *probegate;
+    short probepin;
+    log_tool *probesimtype;
+    short baselinecolor;*/
+
+    /*log_hnrec *hnbase;
+    log_htrec *htbase;
+    log_htrec *htlast;*/
+
+    long fastspeed;
+    long fastmin;
+    long fastmax;
+    long fastrate;
+
+    long singlestepcount;
+
+    double time;
+    double prevtimestep;
+
+    /*log_simstatekinds simstate;
+    log_simstatekinds oldsimstate;
+
+    log_tool *simstatetool;
+    log_tool *oldsimstatetool;*/
+
+    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 */
+    int markers;         /** Printing markers are defined */
+    int invisible;       /** Gates and wires are invisible */
+    int textinvisible;   /** Lablels and boxes are invisible */
+    int pnuminvisible;   /** Pin numbers are invisible */
+    int dotsvisible;      /** Are "red dots" on or off normally? */
+    int showconflicts;   /** Show onlyconflict */
+    int resetflag;       /** "Reset" command has been given */
+    int pwrflag;         /** Simulator is turned on */
+    int initdone;       /** Done with program initialization */
+    int refrflag;        /** Refreshing all displays */
+
+    int busyflag;        /** Flag for idling simulations */
+
+    short markerx1;
+    short markery1;
+    short markerx2;
+    short markery2;
+
+    /*m_tablet_info t;
+    m_tablet_info t0;*/
+    int startpoint;
+    int stillnear;
+    int incircuit;
+
+    short gridx;
+    short gridy;
+    short posx;
+    short posy;
+    short oldx;
+    short oldy;
+    short cx_min;
+    short cy_min;
+    short cx_max;
+    short cy_max;
+    /** Area covered bu cyrsor */
+
+    ///FILE **tracefile;
+
+    char *homedirname;
+
+    //log_tool *toolbase;
+
+    /*log_hooks_t hook;
+    log_colorrec color;*/
+
+    long curstamp;
+    long labelstamp;                /** Changes to labels */
+    long boxstamp;                  /** Changes to boxes */
+    long msgstamp;                  /** Clearing messages screen */
+    long refrstamp;                 /** Clearing graphics screen */
+    long nattrstamp;                /** Changes to note attributes */
+    long gattrstamp;                /** Changes to gate attributes */
+    long sigstamp;                  /** Changes to signal table */
+    long loadstamp;                 /** A page was loaded */
+    long colorstamp;                /** Color assignment have changes */
+    long resetstamp;   /* Simulation has been reset */
+    long markerstamp;               /** Page markers moved */
+
+    /*log_krec *probekind;
+    strlist_t *actstrlist;
+    log_hook2_t *hook2;
+    log_hwrec *probehwire;
+    log_vwrec *probevwire;*/
+    long actx2;
+    long acty2;
+    char[17] genfunc;
+}