add color to error printing + reorganise options

This commit is contained in:
zawz 2021-05-25 16:12:02 +02:00
parent 9ddf23dd4b
commit 05723fe994
7 changed files with 74 additions and 95 deletions

View file

@ -18,10 +18,20 @@ CXXFLAGS= -I$(IDIR) -Wall -pedantic -std=c++20
ifeq ($(DEBUG),true)
# debugging flags
CXXFLAGS += -g
RODIR = $(ODIR)/debug
else
# release flags
CXXFLAGS += -Ofast
RODIR = $(ODIR)/release
endif
ifeq ($(STATIC),true)
# static links
LDFLAGS += -l:libztd.a
else
# dynamic links
LDFLAGS += -lztd
endif
ifeq ($(PROFILE),true)
CXXFLAGS += -pg
@ -31,51 +41,49 @@ ifneq ($(RELEASE), true)
VSUFFIX=-dev-$(SHA_SHORT)
endif
ifeq ($(STATIC),true)
# static links
LDFLAGS += -l:libztd.a
else
# dynamic links
LDFLAGS += -lztd
endif
## END CONFIG ##
$(shell ./generate_version.sh)
$(shell ./generate_shellcode.sh)
$(shell mkdir -p $(ODIR))
$(shell mkdir -p $(RODIR))
$(shell mkdir -p $(BINDIR))
# automatically find .h and .hpp
DEPS = $(shell find $(IDIR) -type f -regex '.*\.hp?p?' ! -name 'g_version.h' ! -name 'g_shellcode.h')
DEPS = $(shell find $(IDIR) -type f -regex '.*\.hp?p?')
# automatically find .c and .cpp and make the corresponding .o rule
OBJ = $(shell find $(SRCDIR) -type f -regex '.*\.cp?p?' | sed 's|\.cpp|.o|g;s|\.c|.o|g;s|^$(SRCDIR)/|$(ODIR)/|g')
OBJ = $(shell find $(SRCDIR) -type f -regex '.*\.cp?p?' | sed 's|\.cpp|.o|g;s|\.c|.o|g;s|^$(SRCDIR)/|$(RODIR)/|g')
build: lxsh $(OBJ) $(DEPS)
build: $(BINDIR)/$(NAME)
$(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS)
# specific files for autogenerated headers
$(OBJDIR)/options.o: $(SRCDIR)/options.cpp $(DEPS) $(IDIR)/g_version.h
$(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
$(OBJDIR)/shellcode.o: $(SRCDIR)/shellcode.cpp $(DEPS) $(IDIR)/g_shellcode.h
$(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/options.o: $(SRCDIR)/options.cpp $(DEPS) $(IDIR)/g_version.h
$(OBJDIR)/debashify.o: $(SRCDIR)/debashify.cpp $(DEPS) $(IDIR)/g_shellcode.h
$(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/shellcode.o: $(SRCDIR)/shellcode.cpp $(DEPS) $(IDIR)/g_shellcode.h
# generic files
$(RODIR)/%.o: $(SRCDIR)/%.c $(DEPS)
$(CC) $(CXXFLAGS) -c -o $@ $<
$(ODIR)/debashify.o: $(SRCDIR)/debashify.cpp $(DEPS) $(IDIR)/g_shellcode.h
$(RODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
$(CC) $(CXXFLAGS) -c -o $@ $<
lxsh: $(OBJ)
$(CC) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
$(BINDIR)/$(NAME): $(OBJ)
$(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ $^
test: $(BINDIR)/$(NAME)
$(BINDIR)/$(NAME)
clean:
rm $(ODIR)/*.o gmon.out
rm $(ODIR)/*/*.o
clear:
rm $(BINDIR)/$(NAME)

View file

@ -102,14 +102,16 @@ class format_error : public std::exception
{
public:
//! @brief Conctructor
inline format_error(const std::string& what, const std::string& origin, const std::string& data, int where) { desc=what; index=where; filename=origin; sdat=data; }
inline format_error(const std::string& what, parse_context const& ctx) { desc=what; index=ctx.i; filename=ctx.filename; sdat=ctx.data; }
inline format_error(const std::string& what, const std::string& origin, const std::string& data, int where, std::string level="error") { desc=what; index=where; filename=origin; sdat=data; severity=level; }
inline format_error(const std::string& what, parse_context const& ctx, std::string level="error") { desc=what; index=ctx.i; filename=ctx.filename; sdat=ctx.data; severity=level; }
//! @brief Error message
inline const char * what () const throw () {return desc.c_str();}
//! @brief Origin of the data, name of imported file, otherwise empty if generated
inline const char * origin() const throw () {return filename.c_str();}
//! @brief Data causing the exception
inline const char * data() const throw () {return sdat.c_str();}
//! @brief Severity of the exception
inline const std::string level() const throw () {return severity.c_str();}
//! @brief Where the error is located in the data
inline const int where () const throw () {return index;}
private:
@ -117,6 +119,7 @@ private:
int index;
std::string filename;
std::string sdat;
std::string severity;
};
// objects

View file

@ -148,8 +148,5 @@ int _exec(std::string const& bin, std::vector<std::string> const& args);
std::string stringReplace(std::string subject, const std::string& search, const std::string& replace);
void printFormatError(format_error const& e, bool print_line=true);
void printErrorIndex(const char* in, const int index, const std::string& message, const std::string& origin, bool print_line=true);
int execute(shmain* sh, std::vector<std::string>& args);
#endif //UTIL_HPP

View file

@ -30,19 +30,20 @@ ztd::option_set options( {
ztd::option('R', "no-resolve", false, "Don't resolve %resolve commands"),
ztd::option("no-extend", false, "Don't add lxsh extension functions"),
ztd::option("debashify", false, "Attempt to turn a bash-specific script into a POSIX shell script"),
ztd::option("\r [var/fct processing]"),
ztd::option("minify-var", false, "Minify variable names"),
ztd::option("minify-fct", false, "Minify function names"),
ztd::option("remove-unused", false, "Remove unused functions and variables"),
ztd::option("list-cmd", false, "List all commands invoked in the script"),
ztd::option("\r [Variable processing]"),
ztd::option("exclude-var", true, "List of matching regex to ignore for variable processing", "list"),
ztd::option("exclude-fct", true, "List of matching regex to ignore for function processing", "list"),
ztd::option("no-exclude-reserved",false, "Don't exclude reserved variables"),
ztd::option("minify-var", false, "Minify variable names"),
ztd::option("list-var", false, "List all variables set and invoked in the script"),
ztd::option("list-var-def", false, "List all variables set in the script"),
ztd::option("list-var-call", false, "List all variables invoked in the script"),
ztd::option("list-fct", false, "List all functions defined in the script"),
ztd::option("list-cmd", false, "List all commands invoked in the script"),
ztd::option("remove-unused", false, "Remove unused functions and variables"),
ztd::option("unset-var", false, "Add 'unset' to all vars at the start of the script to avoid environment interference")
ztd::option("unset-var", false, "Add 'unset' to all variables at the start of the script to avoid environment interference"),
ztd::option("\r [Function processing]"),
ztd::option("exclude-fct", true, "List of matching regex to ignore for function processing", "list"),
ztd::option("minify-fct", false, "Minify function names"),
ztd::option("list-fct", false, "List all functions defined in the script")
} );
bool g_cd=false;
@ -96,9 +97,8 @@ ztd::option_set create_resolve_opts()
void print_help(const char* arg0)
{
printf("%s [options] <file> [arg...]\n", arg0);
printf("Link extended shell\n");
printf("Include files and resolve commands on build time\n");
printf("See --help-commands for help on linker commands\n");
printf("Extended shell linker\n");
printf("Include files, resolve commands on build time, process and minify shell code\n");
printf("\n");
printf("Options:\n");
options.print_help(4,25);

View file

@ -41,13 +41,15 @@ std::string unexpected_token(std::string const& s)
void parse_error(std::string const& message, parse_context& ctx)
{
printFormatError(format_error(message, ctx.filename, ctx.data, ctx.i));
printFormatError(format_error(message, ctx));
ctx.has_errored=true;
}
void parse_error(std::string const& message, parse_context& ctx, uint64_t i)
{
printFormatError(format_error(message, ctx.filename, ctx.data, i));
parse_context newctx = ctx;
newctx.i = i;
printFormatError(format_error(message, newctx));
ctx.has_errored=true;
}

View file

@ -5,7 +5,7 @@
#include "struc_helper.hpp"
const std::map<const std::string, const lxsh_fct> lxsh_extend_fcts = {
{ "_lxsh_random", { "[K]", "Generate a random number between 0 and 2^(k*8). Default 2", RANDOM_SH} },
{ "_lxsh_random", { "[K]", "Generate a random number between 0 and 2^(K*8). Default 2", RANDOM_SH} },
{ "_lxsh_random_string", { "[N]", "Generate a random alphanumeric string of length N. Default 20", RANDOM_STRING_SH} },
{ "_lxsh_random_tmpfile", { "[N]", "Get a random TMP filepath, with N random chars. Default 20", RANDOM_TMPFILE_SH, {"_lxsh_random_string"} } }
};

View file

@ -10,6 +10,7 @@
#include <fstream>
#include <ztd/shell.hpp>
#include <ztd/color.hpp>
std::string indenting_string="\t";
@ -213,14 +214,13 @@ std::string repeatString(std::string const& str, uint32_t n)
void printFormatError(format_error const& e, bool print_line)
{
printErrorIndex(e.data(), e.where(), e.what(), e.origin(), print_line);
}
const char* in = e.data();
void printErrorIndex(const char* in, const int index, const std::string& message, const std::string& origin, bool print_line)
{
int i=0, j=0; // j: last newline
int line=1; //n: line #
int in_size=strlen(in);
uint64_t index = e.where();
uint64_t i=0, j=0; // j: last newline
uint64_t line=1; //n: line #
uint64_t in_size=strlen(in);
if(index >= 0)
{
while(i < in_size && i < index)
@ -233,56 +233,25 @@ void printErrorIndex(const char* in, const int index, const std::string& message
i++;
}
while(i < in_size && in[i]!='\n')
{
i++;
}
}
fprintf(stderr, "%s:%u:%u: %s\n", origin.c_str(), line, index-j+1, message.c_str());
std::cerr << ztd::color::b_white;
fprintf(stderr, "%s:%lu:%lu: ", e.origin(), line, index-j+1);
ztd::color level_color;
const std::string& level = e.level();
if(level == "error")
level_color = ztd::color::b_red;
else if(level == "warning")
level_color = ztd::color::b_magenta;
else if(level == "info")
level_color = ztd::color::b_cyan;
std::cerr << level_color << e.level() << ztd::color::none;
fprintf(stderr, ": %s\n", e.what());
if(print_line)
{
std::cerr << std::string(in+j, i-j) << std::endl;
std::cerr << repeatString(" ", index-j) << '^' << std::endl;
}
}
int execute(shmain* sh, std::vector<std::string>& args)
{
std::string data=sh->generate();
std::string filename = basename(args[0]);
// generate path
std::string tmpdir = (getenv("TMPDIR") != NULL) ? getenv("TMPDIR") : "/tmp" ;
std::string dirpath = tmpdir + "/lxsh_" + ztd::sh("tr -dc '[:alnum:]' < /dev/urandom | head -c10");
std::string filepath = dirpath+'/'+filename;
// create dir
if(ztd::exec("mkdir", "-p", dirpath).second)
{
throw std::runtime_error("Failed to create directory '"+dirpath+'\'');
}
// create stream
std::ofstream stream(filepath);
if(!stream)
{
ztd::exec("rm", "-rf", dirpath);
throw std::runtime_error("Failed to write to '"+filepath+'\'');
}
// output
stream << data;
stream.close();
if(ztd::exec("chmod", "+x", filepath).second != 0)
{
ztd::exec("rm", "-rf", dirpath);
throw std::runtime_error("Failed to make '"+filepath+"' executable");
}
// exec
int retval=_exec(filepath, args);
ztd::exec("rm", "-rf", dirpath);
return retval;
}