Quantcast

Encapsulate and enhance the logging facility within Ovale.lua.

Johnny C. Lam [07-18-14 - 19:34]
Encapsulate and enhance the logging facility within Ovale.lua.

Cap the number of lines held by the log to a maximum of 4096 (2^14) lines
to prevent table overflows causing memory allocation errors.  This fixes
the following tickets:

    ticket 392 by @ggrider
    ticket 396 by @sparrowlab
Filename
Ovale.lua
OvaleOptions.lua
diff --git a/Ovale.lua b/Ovale.lua
index b0ce159..97e2b1b 100644
--- a/Ovale.lua
+++ b/Ovale.lua
@@ -22,6 +22,7 @@ local pairs = pairs
 local select = select
 local tconcat = table.concat
 local tostring = tostring
+local unpack = unpack
 local wipe = table.wipe
 local API_GetTime = GetTime
 local API_IsInGroup = IsInGroup
@@ -44,6 +45,10 @@ local OVALE_MSG_PREFIX = addonName
 local self_bug = false
 -- If "traced" flag is set, then the public "trace" property is toggled before the next frame refresh.
 local self_traced = false
+-- Table of lines output using Log() or Logf() methods.
+local self_traceLog = {}
+-- Maximum length of the trace log.
+local OVALE_TRACELOG_MAXLINES = 4096	-- 2^14
 -- Table of strings to display once per session.
 local self_oneTimeMessage = {}
 --</private-static-properties>
@@ -63,7 +68,6 @@ Ovale.checkBoxWidget = {}
 Ovale.listWidget = {}
 -- Flag to activate tracing the function calls for the next frame refresh.
 Ovale.trace = false
-Ovale.traceLog = {}
 --in combat?
 Ovale.enCombat = false
 Ovale.refreshNeeded = {}
@@ -398,17 +402,37 @@ end

 function Ovale:Log(...)
 	if self.trace then
-		local output = { ... }
-		self.traceLog[#self.traceLog + 1] = tconcat(output, "\t")
+		local N = #self_traceLog
+		if N < OVALE_TRACELOG_MAXLINES - 1 then
+			local output = { ... }
+			self_traceLog[N + 1] = tconcat(output, "\t")
+		elseif N == OVALE_TRACELOG_MAXLINES - 1 then
+			self_traceLog[N + 1] = "WARNING: Maximum length of trace log has been reached."
+		end
 	end
 end

 function Ovale:Logf(...)
+	local N = #self_traceLog
 	if self.trace then
-		self.traceLog[#self.traceLog + 1] = self:Format(...)
+		if N < OVALE_TRACELOG_MAXLINES - 1 then
+			self_traceLog[N + 1] = self:Format(...)
+		elseif N == OVALE_TRACELOG_MAXLINES - 1 then
+			self_traceLog[N + 1] = "WARNING: Maximum length of trace log has been reached."
+		end
 	end
 end

+-- Reset/empty the contents of the trace log.
+function Ovale:ClearLog()
+	wipe(self_traceLog)
+end
+
+-- Return the contents of the trace log as a string.
+function Ovale:TraceLog()
+	return tconcat(self_traceLog, "\n")
+end
+
 function Ovale:OneTimeMessage(...)
 	local s = Ovale:Format(...)
 	if not self_oneTimeMessage[s] then
diff --git a/OvaleOptions.lua b/OvaleOptions.lua
index c35b13e..523755f 100644
--- a/OvaleOptions.lua
+++ b/OvaleOptions.lua
@@ -25,9 +25,6 @@ local OvaleState = nil
 local format = string.format
 local strgmatch = string.gmatch
 local strgsub = string.gsub
-local tconcat = table.concat
-local tostring = tostring
-local wipe = table.wipe
 local API_GetSpellInfo = GetSpellInfo
 local API_GetTime = GetTime
 local API_UnitClass = UnitClass
@@ -519,7 +516,7 @@ local self_options =
 							type = "execute",
 							name = "Trace next frame",
 							func = function()
-								wipe(Ovale.traceLog)
+								Ovale:ClearLog()
 								Ovale.trace = true
 								Ovale:Logf("=== Trace @%f", API_GetTime())
 							end,
@@ -591,7 +588,7 @@ local self_options =
 							type = "input",
 							multiline = 25,
 							width = "full",
-							get = function() return tconcat(Ovale.traceLog, "\n") end,
+							get = function() return Ovale:TraceLog() end,
 						},
 					},
 				},