Commit 5dbc56d8 authored by Cédric VALENSI's avatar Cédric VALENSI

Sync

parent a43291d4
......@@ -317,7 +317,7 @@ find_path(RPMBUILD_PATH NAMES rpmbuild) # look for rpmbuild
find_path(DPKG_DEB_PATH NAMES dpkg-deb) # look for dpkg-deb
SET(CPACK_PACKAGE_VERSION_MAJOR "2")
SET(CPACK_PACKAGE_VERSION_MINOR "4")
SET(CPACK_PACKAGE_VERSION_MINOR "5")
SET(CPACK_PACKAGE_VERSION_PATCH "0")
# ---- Check if at least one package generator has been found
......
.\" File generated using by MAQAO.
.TH MAQAO-ANALYZE "1" "04/20/2018" "MAQAO-ANALYZE 2.4.0" "User Commands"
.TH MAQAO-ANALYZE "1" "06/18/2018" "MAQAO-ANALYZE 2.5.0" "User Commands"
.SH NAME
maqao-analyze \- manual page for maqao analyze module.
.SH SYNOPSIS
......
.\" File generated using by MAQAO.
.TH MAQAO-MADRAS "1" "" "MAQAO-MADRAS 2.4.0" "User Commands"
.TH MAQAO-MADRAS "1" "" "MAQAO-MADRAS 2.5.0" "User Commands"
.SH NAME
maqao-madras \- manual page for maqao madras module.
.SH SYNOPSIS
......
.\" File generated using by MAQAO.
.TH MAQAO "1" "04/20/2018" "MAQAO 2.4.0" "User Commands"
.TH MAQAO "1" "06/18/2018" "MAQAO 2.5.0" "User Commands"
.SH NAME
maqao \- manual page for maqao module.
.SH SYNOPSIS
......
......@@ -130,6 +130,11 @@ void *lc_malloc0(unsigned long size)
return ptr;
}
void* lc_calloc(unsigned long nmemb, unsigned long size)
{
return lc_malloc0(nmemb * size);
}
char *lc_strdup(const char *str) {
char *ptr;
ptr = lc_malloc(strlen(str) + 1);
......
......@@ -502,6 +502,7 @@ static int* _split_version(const char* str, int* size)
substr[i++] = atoi(strtok(cstr, "."));
while ((tmp = strtok(NULL, ".")) != NULL)
substr[i++] = atoi(tmp);
lc_free (cstr);
(*size) = s;
return (substr);
}
......@@ -536,17 +537,26 @@ int str_compare_version(const char* v1, const char* v2)
else
min_s = s2;
int ret = 0;
for (i = 0; i < min_s; i++) {
if (sv1[i] < sv2[i])
return (1);
else if (sv1[i] > sv2[i])
return (-1);
if (sv1[i] < sv2[i]) {
ret = 1;
break;
}
else if (sv1[i] > sv2[i]) {
ret = -1;
break;
}
}
if (s1 < s2 && sv2[s1] > 0)
return (1);
else if (s1 > s2 && sv1[s2] > 0)
return (-1);
return (0);
if (ret == 0) {
if (s1 < s2 && sv2[s1] > 0)
ret = 1;
else if (s1 > s2 && sv1[s2] > 0)
ret = -1;
}
lc_free (sv1);
lc_free (sv2);
return ret;
}
/*
......
......@@ -506,6 +506,8 @@ extern void *lc_malloc (unsigned long size);
*/
extern void *lc_malloc0 (unsigned long size);
extern void* lc_calloc(unsigned long nmemb, unsigned long size);
/**
* Custom strdup using lc_malloc
* \param str A string to duplicate
......
This diff is collapsed.
......@@ -513,6 +513,8 @@ static void __file_free(void* f)
if (file->vendor)
lc_free(file->vendor);
if (file->producer)
lc_free(file->producer);
if (file->name)
lc_free(file->name);
if (file->dir)
......@@ -1786,6 +1788,7 @@ void dwarf_api_close_light(DwarfAPI* api)
if (api->fct_array_size > 0)
lc_free(api->fct_array);
lc_free(api->dbg);
lc_free(api->elf_name);
lc_free(api);
}
......
......@@ -695,7 +695,6 @@ DwarfAPI* asmfile_debug_handle_link(const char* libpath, asmfile_t* asmf)
//DBGMSG ("===> asmfile debug = %p\n", asmf->debug->data);
const char* scnname = ".gnu_debuglink";
const char* os_debug_path = "/usr/lib/debug/";
char* libpath_copy = lc_strdup(libpath);
// Looks into asmf if a section called .gnu_debuglink is present
int i = 0;
......@@ -717,13 +716,12 @@ DwarfAPI* asmfile_debug_handle_link(const char* libpath, asmfile_t* asmf)
}
if (debugfile_name == NULL) {
lc_free(libpath_copy);
return NULL;
}
// At this point, debugfile_name contains the basename of the library to load and libpath
// contains the full name of the library
libpath_copy = lc_dirname(libpath_copy);
char *libpath_copy = lc_dirname(libpath);
DBGMSG("===> libpath : [%s]\n", libpath_copy);
DBGMSG("===> dirname(libpath) : [%s]\n", libpath_copy);
DBGMSG("===> os_debug_path : [%s]\n", os_debug_path);
......@@ -734,7 +732,7 @@ DwarfAPI* asmfile_debug_handle_link(const char* libpath, asmfile_t* asmf)
* (strlen(os_debug_path) + strlen(libpath_copy)
+ strlen(debugfile_name) + 5));
sprintf(linkname, "%s%s/%s", os_debug_path, libpath_copy, debugfile_name);
lc_free(libpath_copy);
lc_free(libpath_copy); lc_free(debugfile_name);
DBGMSG("===> Debug version of the library : %s\n", linkname);
FILE* f = fopen(linkname, "r");
if (f == NULL) {
......
......@@ -608,7 +608,7 @@ int madras_set_branch_target(elfdis_t* ed, insn_t* in, int64_t addr, int update)
{
char buf[STR_INSN_BUF_SIZE];
insn_print(in, buf, sizeof(buf));
TRACE(ed, "madras_linkbranch_toaddr(in=%#"PRIx64":%s,addr=%#"PRIx64")\n", insn_get_addr(in), (in)?buf:NULL, addr);
TRACE(ed, "madras_set_branch_target(in=%#"PRIx64":%s,addr=%#"PRIx64", update=%d)\n", insn_get_addr(in), (in)?buf:NULL, addr, update);
insn_t* dst = asmfile_get_insn_by_addr(ed->afile, addr);
if (!dst) {
ERRMSG("No instruction found at address %#"PRIx64"\n", addr);
......@@ -654,6 +654,9 @@ insn_t* madras_get_oppositebranch(elfdis_t* ed, insn_t* in, int64_t addr,
if (ed == NULL) {
return NULL;
}
char buf[STR_INSN_BUF_SIZE];
insn_print(in, buf, sizeof(buf));
TRACE(ed, "madras_get_oppositebranch(in=%#"PRIx64":%s,addr=%#"PRIx64")\n", insn_get_addr(in), (in)?buf:NULL, addr);
if (in == NULL)
insn = asmfile_get_insn_by_addr(ed->afile, addr);
else
......@@ -770,6 +773,7 @@ boolean_t madras_is_file_valid(char* filename, int* archcode, int* typecode)
}
elffile_free(elf);
}
asmfile_free (asmf);
return out;
}
......
......@@ -61,6 +61,8 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/classes/XLSX.lua.in
${CMAKE_CURRENT_SOURCE_DIR}/classes/XLSX.lua @ONLY)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/classes/HTML.lua.in
${CMAKE_CURRENT_SOURCE_DIR}/classes/HTML.lua @ONLY)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/classes/TEXT.lua.in
${CMAKE_CURRENT_SOURCE_DIR}/classes/TEXT.lua @ONLY)
ADD_CUSTOM_TARGET(distclean_builtin
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/classes/Help.lua
......@@ -70,5 +72,8 @@ ADD_CUSTOM_TARGET(distclean_builtin
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/classes/MDSAPI.lua
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/classes/Utils.lua
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/classes/XLSX.lua
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/classes/HTML.lua
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/classes/TEXT.lua
VERBATIM
)
......@@ -38,10 +38,11 @@ end
-- | Add a TLS variable
function add_tls_var(patch,typ,size,init)
-- Set parameter is_init to 1 to force variable being considered initialised
function add_tls_var(patch,typ,size,init, is_init)
local m = patch.madras
return { typ = "tlsvar"
, value = m:tlsvar_new(typ,size,init)
, value = m:tlsvar_new(typ,size,init, is_init)
}
end
......
......@@ -316,17 +316,17 @@ function find_matching_instru(project,module,instru_config)
end
-- | Perform a custom instrumentation
function project:perform_custom_instru(proj,module,instru_config,instrument, check_reuse)
function project:perform_custom_instru(proj,module,instru_config,instrument, check_reuse, verbose_lvl)
-- Trye to reuse an existing instrumentation
local instru,reusing = find_matching_instru(proj,module,instru_config, check_reuse)
if reusing and check_reuse ~= false then
print(string.format("[%s] Reusing previous instrumentation %d", string.upper(module), instru["id"]))
Message:print(string.format("[%s] Reusing previous instrumentation %d", string.upper(module), instru["id"]), verbose_lvl, 1)
return instru
end
print(string.format("[%s] Performing instrumentation %d...", string.upper(module), instru["id"]))
Message:print(string.format("[%s] Performing instrumentation %d...", string.upper(module), instru["id"]), verbose_lvl, 1)
if fs.exists (instru["path"]) == false then
local ret = lfs.mkdir(instru["path"])
......@@ -409,7 +409,7 @@ function project:load_instru(proj,module,instru_id)
end
-- | Run an instrumented binary
function project:run_instru(proj, module, instru_id, run_cmd)
function project:run_instru(proj, module, instru_id, run_cmd, display_output, verbose_lvl)
local instru = project:load_instru(proj,module,instru_id)
local instru_path = instru["path"]
......@@ -444,13 +444,13 @@ function project:run_instru(proj, module, instru_id, run_cmd)
-- Set environment variable for run directory
-- Execute binary
print(string.format("[%s] Executing instrumented binary (instrumentation %d, run %d)...",
string.upper(module), instru_id, run_id))
Message:print(string.format("[%s] Executing instrumented binary (instrumentation %d, run %d)...",
string.upper(module), instru_id, run_id), verbose_lvl, 1)
local ld_lib_path = os.getenv ("LD_LIBRARY_PATH") or ""
local run_env = "LD_LIBRARY_PATH="..instru_path..":"..ld_lib_path.." "
local run_bin = string.format("MAQAO_RUN_DIR=%s %s", run_path, string.gsub(run_cmd, "{MAQAO_BIN}", bin_path))
print("[MAQAO] Command: "..run_env..run_bin)
Message:print("[MAQAO] Command: "..run_env..run_bin, verbose_lvl, 2)
-- Used to update the environment in order to use modified libraries if needed
-- The path to the instru%d%d%d%d directory must be added to LD_LIBRARY_PATH
......@@ -461,7 +461,10 @@ function project:run_instru(proj, module, instru_id, run_cmd)
-- Saving output
file_write(run_path .. "/output", res)
if (display_output == true) then
Message:print("[MAQAO] Command standard output:", verbose_lvl, 1)
Message:print(res, verbose_lvl, 0)
end
local run = {}
run["path"] = run_path
......
......@@ -38,6 +38,12 @@
#include <string.h> /* strcmp... */
#include <math.h> /* log2 */
#include <inttypes.h>
#include <stdio.h>
#include <sys/ioctl.h>
/* LUA specific includes */
#include <lua.h> /* declares lua_* functions */
......@@ -264,7 +270,7 @@ static int demangle_string(lua_State *L)
/** Returns a formatted timestamp, including the microseconds*/
static int gen_timestamp(lua_State *L)
{
char* str[256];
char str[256];
int res = generate_timestamp(str, 256);
if (res == EXIT_SUCCESS)
lua_pushstring(L, str);
......@@ -282,6 +288,31 @@ static int maqao_sleep (lua_State *L)
return 0;
}
static int maqao_wait_SIGINT (lua_State *L)
{
int ret = -1;
int delay = luaL_checkinteger (L, 1);
if (delay > 0)
#ifdef _WIN32
{
size_t len = strlen ("ping -n 127.0.0.1 >nul") + strlen ("99999") + 1;
char cmd [len];
snprintf (cmd, len, "ping -n %d 127.0.0.1 >nul", delay);
ret = system (cmd);
}
#else
{
size_t len = strlen ("sleep ") + strlen ("99999") + 1;
char cmd [len];
snprintf (cmd, len, "sleep %d", delay);
ret = system (cmd);
}
#endif
lua_pushinteger(L, ret);
return 1;
}
static int maqao_isatty (lua_State *L)
{
luaL_checktype(L, 1, LUA_TUSERDATA);
......@@ -292,6 +323,17 @@ static int maqao_isatty (lua_State *L)
return 1;
}
static int maqao_get_term_size (lua_State *L)
{
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
lua_pushinteger(L, w.ws_col);
lua_pushinteger(L, w.ws_row);
return 2;
}
void ao_init_help(lua_State *L, help_t* help)
{
if (help == NULL)
......@@ -507,8 +549,14 @@ int luaopen_abstract_objects_c(lua_State * L)
lua_pushcfunction(L, maqao_sleep);
lua_setglobal(L, "maqao_sleep");
lua_pushcfunction(L, maqao_wait_SIGINT);
lua_setglobal(L, "maqao_wait_SIGINT");
lua_pushcfunction(L, maqao_isatty);
lua_setglobal(L, "maqao_isatty");
lua_pushcfunction(L, maqao_get_term_size);
lua_setglobal(L, "maqao_get_term_size");
return 1;
}
......@@ -39,3 +39,5 @@ dofile("@LUA_SCRIPTS_PATH@/built_in/classes/MDSAPI.lua");
dofile("@LUA_SCRIPTS_PATH@/built_in/classes/XLSX.lua");
dofile("@LUA_SCRIPTS_PATH@/built_in/classes/HTML.lua");
dofile("@LUA_SCRIPTS_PATH@/built_in/classes/Stream.lua");
dofile("@LUA_SCRIPTS_PATH@/built_in/classes/TEXT.lua");
dofile("@LUA_SCRIPTS_PATH@/built_in/classes/TextOutput.lua");
......@@ -18,9 +18,10 @@
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
---
HTML._nb_tabs_table = 0
HTML._nb_actions = 0
HTML._debug = false
HTML._nb_tabs_table = 0
HTML._nb_actions = 0
HTML._nb_action_menus = 0
HTML._debug = false
-- ----------------------------------------------------------------------------
......
......@@ -111,8 +111,48 @@ function HTML:create_action (parameters)
end
haction.id = HTML._nb_actions
HTML._nb_actions = HTML._nb_actions + 1
return haction
end
-- ----------------------------------------------------------------------------
-- Action Menu
-- Create the class
HTML_action_menu = {}
-- Create the class meta
HTML_action_menuMeta = {}
HTML_action_menuMeta._NAME = "HTML_action_menu"
HTML_action_menuMeta.__index = HTML_action_menu
--- Create a menu of actions
--@return an initialized empty action_menu object
function HTML:create_action_menu ()
local hmenu = {}
setmetatable (hmenu, HTML_action_menuMeta)
hmenu.actions = {}
hmenu.id = HTML._nb_action_menus
HTML._nb_action_menus = HTML._nb_action_menus + 1
return hmenu
end
--- Add an action to an action_menu
-- @param action An HTML_action to add
-- @param param A string parameter associated to the action
function HTML_action_menu:add_action (text, action, param)
if self == nil
or action == nil
or text == nil then
return
end
table.insert (self.actions, {text = text, action = action, param = param})
end
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -52,6 +52,10 @@ end
-- col_name = <string>, -- Displayed name of the i-th column
-- width = <int>, -- Column size (percentage of the width)
-- is_centered = <boolean>, -- True if the content must be centered, else false
-- is_optionnal = <boolean>, -- False (default) is the column is always displayed, true
-- if it can be hidden
-- is_displayed = <boolean>, -- If the column is optionnal, specify if the column is displayed
-- -- at the page loading (true) or not (false, default)
-- }
-- @param data Data to displayed. It is an iterative table with the following format:
-- data[i] = {
......@@ -90,19 +94,11 @@ function HTML:create_html_table (header, data, _type, custom_style)
htable.row_actions = {}
htable.reg_actions = nil
htable.actions = {}
htable.action_menus = {}
htable.is_action = false
htable.width = 20
htable.is_action_menu= false
htable.custom_style = custom_style
-- Compute table width
-- -------------------------------------------------------------------------
-- Needed to center the table in the <div>
for _, head in ipairs (htable.header) do
if head.width == nil then
head.width = 150
end
htable.width = htable.width + head.width
end
-- Rename 'id' key
......@@ -140,7 +136,7 @@ end
-- If only the line is specified, the action is triggered when there is a click on the corresponding row
-- If only the column is specified, the action is triggered when there is a click on the corresponding column
-- If none of them is specified, the action is triggered when there is a click anywher on the table
-- @param html_action An acction to link
-- @param html_action An action or a menu to link
-- @param line Index of the row the action is linked to
-- @param column Index of the column the action is linked to
-- @param param An optionnal string which will be used as parameter when the action is call
......@@ -150,6 +146,7 @@ function HTML_table:add_action (html_action, line, column, param)
if type (html_action) ~= "table" then
return false
end
local atype = getmetatable (html_action)._NAME
-- Add an action to a table ------------------------------------------------
-- Regular action
......@@ -160,8 +157,11 @@ function HTML_table:add_action (html_action, line, column, param)
self.reg_action_p = {}
end
table.insert (self.reg_action, {action = html_action, param = param})
self.is_action = true
if atype == "HTML_action_menu" then
table.insert (self.reg_action, {action = html_action, param = param, type="m"})
else
table.insert (self.reg_action, {action = html_action, param = param, type="a"})
end
-- located action
elseif type (column) == "number"
......@@ -175,8 +175,11 @@ function HTML_table:add_action (html_action, line, column, param)
self.loc_actions[line][column] = {}
end
table.insert (self.loc_actions[line][column], {action = html_action, param = param})
self.is_action = true
if atype == "HTML_action_menu" then
table.insert (self.loc_actions[line][column], {action = html_action, param = param, type="m"})
else
table.insert (self.loc_actions[line][column], {action = html_action, param = param, type="a"})
end
-- row action
elseif (type (column) ~= "number"
......@@ -187,8 +190,11 @@ function HTML_table:add_action (html_action, line, column, param)
self.row_actions[line] = {}
end
table.insert (self.row_actions[line], {action = html_action, param = param})
self.is_action = true
if atype == "HTML_action_menu" then
table.insert (self.row_actions[line], {action = html_action, param = param, type="m"})
else
table.insert (self.row_actions[line], {action = html_action, param = param, type="a"})
end
-- column action
elseif type (column) == "number"
......@@ -199,13 +205,22 @@ function HTML_table:add_action (html_action, line, column, param)
self.col_actions[column] = {}
end
table.insert (self.col_actions[column], {action = html_action, param = param})
self.is_action = true
if atype == "HTML_action_menu" then
table.insert (self.col_actions[column], {action = html_action, param = param, type="m"})
else
table.insert (self.col_actions[column], {action = html_action, param = param, type="a"})
end
else
return false
end
self.actions[html_action.id] = html_action
if atype == "HTML_action_menu" then
self.is_action_menu = true
self.action_menus[html_action.id] = html_action
else
self.is_action = true
self.actions[html_action.id] = html_action
end
return true
end
......@@ -29,29 +29,38 @@ Message.adv_output = false;
Message.msg_output = true;
Message.exit_mode = "os";
---Print debug information
---Print a message
-- @param str String to display
function Message:__display(str,add_call_depth)
if(type(str) == "string" and Message.msg_output == true) then
if(Message.adv_output == true) then
--local debug_info = Message:get_env_info(add_call_depth);
local debug_info = ""
str = debug_info..str;
end
print(str);
end
function Message:__display(str)
if(type(str) == "string" and Message.msg_output == true) then
print(str);
end
end
function Message:rawprint(str,add_call_depth)
Message:__display(str,add_call_depth);
if(Message.adv_output == true) then
local debug_info = Message:get_env_info(add_call_depth);
str = debug_info..str;
end
Message:__display(str);
end
function Message:temp(str)
Message:__display("Temp: "..str);
function Message:temp(str, verbose_lvl, msg_lvl)
Message:__display("Temp: "..str, verbose_lvl, msg_lvl);
end
--- Displays a message without prefix - equivalent to C macro STDMSG
-- @param str String to display
-- @param verbose_lvl Current verbosity level of the application (optional)
-- @param msg_lvl Minimal verbose level for which the message must be displayed (optional)
function Message:print(str, verbose_lvl, msg_lvl)
if (verbose_lvl == nil or msg_lvl == nil or msg_lvl <= verbose_lvl) then
Message:__display(str, verbose_lvl, msg_lvl);
end
end
function Message:info(str)
Message:__display("Info: "..str);
function Message:info(str, verbose_lvl, msg_lvl)
Message:print("Info: "..str, verbose_lvl, msg_lvl);
end
function Message:warn(str)
......
---
-- Copyright (C) 2004 - 2018 Université de Versailles Saint-Quentin-en-Yvelines (UVSQ)
--
-- This file is part of MAQAO.
--
-- MAQAO is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public License
-- as published by the Free Software Foundation; either version 3
-- of the License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
---
TEXT = {}
-- Create the class meta
TEXTMeta = {}
TEXTMeta._NAME = "TEXT"
TEXTMeta.__index = TEXT
function TEXT:new()
local text = {};
setmetatable(text,TEXTMeta);
text.numbered = true
text.header_1 = 0
text.header_2 = 0
text.header_3 = 0
text.header_4 = 0
text.header_5 = 0
return text;
end
dofile ("@LUA_SCRIPTS_PATH@/built_in/classes/TEXT/text.lua")
\ No newline at end of file
---
-- Copyright (C) 2004 - 2018 Université de Versailles Saint-Quentin-en-Yvelines (UVSQ)
--
-- This file is part of MAQAO.
--
-- MAQAO is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public License
-- as published by the Free Software Foundation; either version 3
-- of the License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
---
-- ///////////////////////////////////////////////////////////////////////// --
-- PRIVATE FUNCTIONS --
-- ///////////////////////////////////////////////////////////////////////// --
local function __handle_level (_obj, lvl)
if _obj.numbered ~= true then
return ""
end
if lvl == 1 then
return _obj.header_1.." - "
elseif lvl == 2 then
return _obj.header_1..".".._obj.header_2.." - "
elseif lvl == 3 then
return _obj.header_1..".".._obj.header_2..".".._obj.header_3.." - "
elseif lvl == 4 then
return _obj.header_1..".".._obj.header_2..".".._obj.header_3..".".._obj.header_4.." - "
elseif lvl == 5 then
return _obj.header_1..".".._obj.header_2..".".._obj.header_3..".".._obj.header_4..".".._obj.header_5.." - "
else
return ""
end
return ""
end
local function __display_header_box (_obj, text, c, lvl)
local x = maqao_get_term_size()
local str_line = "+"..string.rep (c, x - 2).."+"
local str_text = ""
if text == nil then
text = __handle_level (_obj, lvl)
else
text = __handle_level (_obj, lvl)..text
end
if text == nil then
str_text = "+"..string.rep (" ", x - 2).."+"
else