Skip to content

Commit 85ccc66

Browse files
authored
Merge pull request darktable-org#74 from wpferguson/libraries
Libraries
2 parents b04e322 + dab0282 commit 85ccc66

File tree

8 files changed

+1362
-93
lines changed

8 files changed

+1362
-93
lines changed

lib/dtutils.lua

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
local dtutils = {}
2+
3+
dtutils.libdoc = {
4+
Name = [[dtutils]],
5+
Synopsis = [[A Darktable lua utilities library]],
6+
Usage = [[local du = require "lib/dtutils"]],
7+
Description = [[dtutils provides a common library of functions used to build
8+
lua scripts. There are also sublibraries that provide more functions.]],
9+
Return_Value = [[du - library - the library of functions]],
10+
Limitations = [[]],
11+
Example = [[]],
12+
See_Also = [[dtutils.debug(3), dtutils.file(3), dtutils.log(3), dtutils.string(3)]],
13+
Reference = [[]],
14+
License = [[This program is free software: you can redistribute it and/or modify
15+
it under the terms of the GNU General Public License as published by
16+
the Free Software Foundation; either version 3 of the License, or
17+
(at your option) any later version.
18+
19+
This program is distributed in the hope that it will be useful,
20+
but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
GNU General Public License for more details.
23+
24+
You should have received a copy of the GNU General Public License
25+
along with this program. If not, see <http://www.gnu.org/licenses/>.]],
26+
Copyright = [[Copyright (C) 2016 Bill Ferguson <[email protected]>.
27+
Copyright (C) 2016 Tobias Jakobs]],
28+
functions = {}
29+
}
30+
31+
local dt = require "darktable"
32+
33+
local log = require "lib/dtutils.log"
34+
35+
dt.configuration.check_version(...,{3,0,0})
36+
37+
dtutils.libdoc.functions["split"] = {
38+
Name = [[split]],
39+
Synopsis = [[split a string on a specified separator]],
40+
Usage = [[local du = require "lib/dtutils"
41+
42+
local result = du.split(str, pat)
43+
str - string - the string to split
44+
pat - string - the pattern to split on]],
45+
Description = [[split separates a string into a table of strings. The strings are separated at each
46+
occurrence of the supplied pattern. The pattern may be any pattern as described in the lua docs.
47+
Each match of the pattern is consumed and not returned.]],
48+
Return_Value = [[result - a table of strings on success, or an empty table on error]],
49+
Limitations = [[]],
50+
Example = [[split("/a/long/path/name/to/a/file.txt", "/") would return a table like
51+
{a, "long", "path", "name", "to", a, "file.txt"}]],
52+
See_Also = [[]],
53+
Reference = [[http://lua-users.org/wiki/SplitJoin]],
54+
License = [[]],
55+
Copyright = [[]],
56+
}
57+
58+
function dtutils.split(str, pat)
59+
local t = {}
60+
local fpat = "(.-)" .. pat
61+
local last_end = 1
62+
local s, e, cap = str:find(fpat, 1)
63+
while s do
64+
if s ~= 1 or cap ~= "" then
65+
table.insert(t,cap)
66+
end
67+
last_end = e+1
68+
s, e, cap = str:find(fpat, last_end)
69+
end
70+
if last_end <= #str then
71+
cap = str:sub(last_end)
72+
table.insert(t, cap)
73+
end
74+
return t
75+
end
76+
77+
dtutils.libdoc.functions["join"] = {
78+
Name = [[join]],
79+
Synopsis = [[join a table of strings with a specified separator]],
80+
Usage = [[local du = require "lib/dtutils"
81+
82+
local result = du.join(tabl, pat)
83+
tabl - a table of strings
84+
pat - a separator]],
85+
Description = [[join assembles a table of strings into a string with the specified pattern
86+
in between each string]],
87+
Return_Value = [[result - string - the joined string on success, or an empty string on failure]],
88+
Limitations = [[]],
89+
Example = [[join({a, "long", "path", "name", "to", a, "file.txt"}, " ") would return the string
90+
"a long path name to a file.txt"]],
91+
See_Also = [[]],
92+
Reference = [[http://lua-users.org/wiki/SplitJoin]],
93+
License = [[]],
94+
Copyright = [[]],
95+
}
96+
97+
function dtutils.join(tabl, pat)
98+
returnstr = ""
99+
for i,str in pairs(tabl) do
100+
returnstr = returnstr .. str .. pat
101+
end
102+
return string.sub(returnstr, 1, -(pat:len() + 1))
103+
end
104+
105+
--[[
106+
NAME
107+
prequire - a protected lua require
108+
109+
SYNOPSIS
110+
local du = require "lib/dtutils"
111+
112+
local result = du.prequire(req_name)
113+
req_name - the filename of the lua code to load without the ".lua" filetype
114+
115+
DESCRIPTION
116+
prequire is a protected require that can survive an error in the code being loaded without
117+
bringing down the calling routine.
118+
119+
RETURN VALUE
120+
result - the code or true on success, otherwise an error message
121+
122+
EXAMPLE
123+
prequire("lib/dtutils.file") which would load lib/dtutils/file.lua
124+
125+
]]
126+
127+
dtutils.libdoc.functions["prequire"] = {
128+
Name = [[prequire]],
129+
Synopsis = [[a protected lua require]],
130+
Usage = [[local du = require "lib/dtutils"
131+
132+
local status, lib = du.prequire(req_name)
133+
req_name - the filename of the lua code to load without the ".lua" filetype]],
134+
Description = [[prequire is a protected require that can survive an error in the code being loaded without
135+
bringing down the calling routine.]],
136+
Return_Value = [[status - boolean - true on success
137+
lib - if status is true, then the code, otherwise an error message]],
138+
Limitations = [[]],
139+
Example = [[local status, lib = prequire("lib/dtutils.file") which would load lib/dtutils/file.lua which
140+
would return a status of true and the reference to the library in lib.]],
141+
See_Also = [[]],
142+
Reference = [[]],
143+
License = [[]],
144+
Copyright = [[]],
145+
}
146+
147+
function dtutils.prequire(req_name)
148+
local status, lib = pcall(require, req_name)
149+
if status then
150+
log.msg(log.info, "Loaded " .. req_name)
151+
else
152+
log.msg(log.info, "Error loading " .. req_name)
153+
end
154+
return status, lib
155+
end
156+
157+
dtutils.libdoc.functions["spairs"] = {
158+
Name = [[spairs]],
159+
Synopsis = [[an iterator that provides sorted pairs from a table]],
160+
Usage = [[local du = require "lib/dtutils"
161+
162+
for key, value in du.spairs(t, order) do
163+
t - table - table of key, value pairs
164+
order - function - an optional function to sort the pairs
165+
if none is supplied, table.sort() is used]],
166+
Description = [[spairs is an iterator that returns key, value pairs from a table in sorted
167+
order. The sorting order is the result of table.sort() if no function is
168+
supplied, otherwise sorting is done as specified in the function.]],
169+
Return_Value = [[]],
170+
Limitations = [[]],
171+
Example = [[HighScore = { Robin = 8, Jon = 10, Max = 11 }
172+
173+
-- basic usage, just sort by the keys
174+
for k,v in spairs(HighScore) do
175+
print(k,v)
176+
end
177+
--> Jon 10
178+
--> Max 11
179+
--> Robin 8
180+
181+
-- this uses an custom sorting function ordering by score descending
182+
for k,v in spairs(HighScore, function(t,a,b) return t[b] < t[a] end) do
183+
print(k,v)
184+
end
185+
--> Max 11
186+
--> Jon 10
187+
--> Robin 8]],
188+
See_Also = [[]],
189+
Reference = [[Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua]],
190+
License = [[]],
191+
Copyright = [[]],
192+
}
193+
194+
-- Sort a table
195+
function dtutils.spairs(_table, order) -- Code copied from http://stackoverflow.com/questions/15706270/sort-a-table-in-lua
196+
-- collect the keys
197+
local keys = {}
198+
for _key in pairs(_table) do keys[#keys + 1] = _key end
199+
200+
-- if order function given, sort by it by passing the table and keys a, b,
201+
-- otherwise just sort the keys
202+
if order then
203+
table.sort(keys, function(a,b) return order(_table, a, b) end)
204+
else
205+
table.sort(keys)
206+
end
207+
208+
-- return the iterator function
209+
local i = 0
210+
return function()
211+
i = i + 1
212+
if keys[i] then
213+
return keys[i], _table[keys[i]]
214+
end
215+
end
216+
end
217+
218+
return dtutils

lib/dtutils/debug.lua

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
--[[
2+
This file is part of darktable,
3+
Copyright (c) 2014 Jérémy Rosen
4+
Copyright (c) 2016 Bill Ferguson
5+
6+
darktable is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
darktable is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with darktable. If not, see <http://www.gnu.org/licenses/>.
18+
]]
19+
--[[
20+
DEBUG HELPERS
21+
A collection of helper functions to help debugging lua scripts.
22+
23+
require it as
24+
25+
dhelpers = require "lib/dtutils.debug"
26+
27+
Each function is documented in its own header
28+
29+
30+
]]
31+
32+
33+
local dt = require "darktable"
34+
local io = require "io"
35+
local table = require "table"
36+
require "darktable.debug"
37+
local log = require "lib/dtutils.log"
38+
local M = {} -- The actual content of the module
39+
40+
M.libdoc = {
41+
Name = [[dtutils.debug]],
42+
Synopsis = [[debugging helpers used in developing darktable lua scripts]],
43+
Usage = [[local dd = require "lib/dtutils.debug"]],
44+
Description = [[dtutils.debug provides an interface to the darktable debugging routines.]],
45+
Return_Value = [[dd - library - the darktable lua debugging helpers]],
46+
Limitations = [[]],
47+
Example = [[]],
48+
See_Also = [[]],
49+
Reference = [[]],
50+
License = log.libdoc.License,
51+
Copyright = [[Copyright (c) 2014 Jérémy Rosen
52+
Copyright (c) 2016 Bill Ferguson
53+
]],
54+
functions = {}
55+
}
56+
57+
M.libdoc.functions["tracepoint"] = {
58+
Name = [[tracepoint]],
59+
Synopsis = [[print out a tracepoint and dump the arguments]],
60+
Usage = [[local dd = require "lib/dtutils.debug"
61+
62+
local result = tracepoint(name, ...)
63+
name - string - the name of the tracepoint to print out
64+
... - arguments - variables to dump the contents of]],
65+
Description = [[tracepoint prints its name and dumps its parameters using
66+
dt.debug]],
67+
Return_Value = [[result - ... - the supplied argument list]],
68+
Limitations = [[]],
69+
Example = [[]],
70+
See_Also = [[]],
71+
Reference = [[]],
72+
License = [[]],
73+
Copyright = [[]],
74+
}
75+
76+
function M.tracepoint(name,...)
77+
log.msg(log.always, 4, "***** "..name.." ****")
78+
params = {...}
79+
log.msg(log.always, 0, dt.debug.dump(params,"parameters"))
80+
return ...;
81+
end
82+
83+
M.libdoc.functions["new_tracepoint"] = {
84+
Name = [[new_tracepoint]],
85+
Synopsis = [[create a function returning a tracepoint]],
86+
Usage = [[local dd = require "lib/dtutils.debug"
87+
88+
local result = new_tracepoint(name, ...)
89+
name - string - the name of the tracepoint to print out
90+
... - arguments - variables to dump the contents of]],
91+
Description = [[A function that returns a tracepoint function with the given name
92+
This is mainly used to debug callbacks.]],
93+
Return_Value = [[result - function - a function that returns the result of a tracepoint]],
94+
Limitations = [[]],
95+
Example = [[register_event(event, dd.new_tracepoint("hit callback"))
96+
97+
will print the following each time the callback is called
98+
99+
**** hit callback ****
100+
<all the callback's parameters dumped>]],
101+
See_Also = [[]],
102+
Reference = [[]],
103+
License = [[]],
104+
Copyright = [[]],
105+
}
106+
107+
function M.new_tracepoint(name)
108+
return function(...) return M.tracepoint(name,...) end
109+
end
110+
111+
112+
M.libdoc.functions["dprint"] = {
113+
Name = [[dprint]],
114+
Synopsis = [[pass a variable to dt.debug.dump and print the results to stdout]],
115+
Usage = [[local dd = require "lib/dtutils.debug"
116+
117+
dd.dprint(var)
118+
var - variable - any variable that you want to see the contents of]],
119+
Description = [[Wrapper around debug.dump, will directly print to stdout,
120+
same calling convention]],
121+
Return_Value = [[]],
122+
Limitations = [[]],
123+
Example = [[]],
124+
See_Also = [[]],
125+
Reference = [[]],
126+
License = [[]],
127+
Copyright = [[]],
128+
}
129+
130+
function M.dprint(...)
131+
log.msg(log.always, 4, dt.debug.dump(...))
132+
end
133+
134+
M.libdoc.functions["terse_dump"] = {
135+
Name = [[terse_dump]],
136+
Synopsis = [[set dt.debug.known to shorten all image dumps to a single line]],
137+
Usage = [[local dd = require "lib/dtutils.debug"
138+
139+
dd.terse_dump()]],
140+
Description = [[terse_dump sets dt.debug.known to shorten all images to a single line.
141+
If you don't need to debug the content of images, this will avoid them flooding your logs]],
142+
Return_Value = [[]],
143+
Limitations = [[]],
144+
Example = [[]],
145+
See_Also = [[]],
146+
Reference = [[]],
147+
License = [[]],
148+
Copyright = [[]],
149+
}
150+
151+
function M.terse_dump()
152+
for _,v in ipairs(dt.database) do
153+
dt.debug.known[v] = tostring(v)
154+
end
155+
end
156+
157+
158+
159+
return M
160+
-- vim: shiftwidth=2 expandtab tabstop=2 cindent
161+
-- kate: tab-indents: off; indent-width 2; replace-tabs on; remove-trailing-space on;

0 commit comments

Comments
 (0)