add color to error printing + reorganise options
This commit is contained in:
parent
9ddf23dd4b
commit
05723fe994
7 changed files with 74 additions and 95 deletions
56
Makefile
56
Makefile
|
|
@ -16,12 +16,22 @@ CC=g++
|
||||||
# compiler flags
|
# compiler flags
|
||||||
CXXFLAGS= -I$(IDIR) -Wall -pedantic -std=c++20
|
CXXFLAGS= -I$(IDIR) -Wall -pedantic -std=c++20
|
||||||
ifeq ($(DEBUG),true)
|
ifeq ($(DEBUG),true)
|
||||||
# debugging flags
|
# debugging flags
|
||||||
CXXFLAGS += -g
|
CXXFLAGS += -g
|
||||||
|
RODIR = $(ODIR)/debug
|
||||||
else
|
else
|
||||||
# release flags
|
# release flags
|
||||||
CXXFLAGS += -Ofast
|
CXXFLAGS += -Ofast
|
||||||
|
RODIR = $(ODIR)/release
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(STATIC),true)
|
||||||
|
# static links
|
||||||
|
LDFLAGS += -l:libztd.a
|
||||||
|
else
|
||||||
|
# dynamic links
|
||||||
|
LDFLAGS += -lztd
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(PROFILE),true)
|
ifeq ($(PROFILE),true)
|
||||||
CXXFLAGS += -pg
|
CXXFLAGS += -pg
|
||||||
|
|
@ -31,51 +41,49 @@ ifneq ($(RELEASE), true)
|
||||||
VSUFFIX=-dev-$(SHA_SHORT)
|
VSUFFIX=-dev-$(SHA_SHORT)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(STATIC),true)
|
|
||||||
# static links
|
|
||||||
LDFLAGS += -l:libztd.a
|
|
||||||
else
|
|
||||||
# dynamic links
|
|
||||||
LDFLAGS += -lztd
|
|
||||||
endif
|
|
||||||
|
|
||||||
## END CONFIG ##
|
## END CONFIG ##
|
||||||
|
|
||||||
|
|
||||||
$(shell ./generate_version.sh)
|
$(shell ./generate_version.sh)
|
||||||
$(shell ./generate_shellcode.sh)
|
$(shell ./generate_shellcode.sh)
|
||||||
$(shell mkdir -p $(ODIR))
|
|
||||||
|
$(shell mkdir -p $(RODIR))
|
||||||
$(shell mkdir -p $(BINDIR))
|
$(shell mkdir -p $(BINDIR))
|
||||||
|
|
||||||
# automatically find .h and .hpp
|
# 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
|
# 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 $@ $<
|
$(CC) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(ODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
|
$(OBJDIR)/shellcode.o: $(SRCDIR)/shellcode.cpp $(DEPS) $(IDIR)/g_shellcode.h
|
||||||
$(CC) $(CXXFLAGS) -c -o $@ $<
|
$(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 $@ $<
|
$(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 $@ $<
|
$(CC) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(ODIR)/debashify.o: $(SRCDIR)/debashify.cpp $(DEPS) $(IDIR)/g_shellcode.h
|
$(RODIR)/%.o: $(SRCDIR)/%.cpp $(DEPS)
|
||||||
$(CC) $(CXXFLAGS) -c -o $@ $<
|
$(CC) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
lxsh: $(OBJ)
|
|
||||||
$(CC) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
|
$(BINDIR)/$(NAME): $(OBJ)
|
||||||
|
$(CC) $(CXXFLAGS) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
test: $(BINDIR)/$(NAME)
|
test: $(BINDIR)/$(NAME)
|
||||||
$(BINDIR)/$(NAME)
|
$(BINDIR)/$(NAME)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm $(ODIR)/*.o gmon.out
|
rm $(ODIR)/*/*.o
|
||||||
|
|
||||||
clear:
|
clear:
|
||||||
rm $(BINDIR)/$(NAME)
|
rm $(BINDIR)/$(NAME)
|
||||||
|
|
|
||||||
|
|
@ -102,14 +102,16 @@ class format_error : public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! @brief Conctructor
|
//! @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, 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) { desc=what; index=ctx.i; filename=ctx.filename; sdat=ctx.data; }
|
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
|
//! @brief Error message
|
||||||
inline const char * what () const throw () {return desc.c_str();}
|
inline const char * what () const throw () {return desc.c_str();}
|
||||||
//! @brief Origin of the data, name of imported file, otherwise empty if generated
|
//! @brief Origin of the data, name of imported file, otherwise empty if generated
|
||||||
inline const char * origin() const throw () {return filename.c_str();}
|
inline const char * origin() const throw () {return filename.c_str();}
|
||||||
//! @brief Data causing the exception
|
//! @brief Data causing the exception
|
||||||
inline const char * data() const throw () {return sdat.c_str();}
|
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
|
//! @brief Where the error is located in the data
|
||||||
inline const int where () const throw () {return index;}
|
inline const int where () const throw () {return index;}
|
||||||
private:
|
private:
|
||||||
|
|
@ -117,6 +119,7 @@ private:
|
||||||
int index;
|
int index;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string sdat;
|
std::string sdat;
|
||||||
|
std::string severity;
|
||||||
};
|
};
|
||||||
|
|
||||||
// objects
|
// objects
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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 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
|
#endif //UTIL_HPP
|
||||||
|
|
|
||||||
|
|
@ -30,19 +30,20 @@ ztd::option_set options( {
|
||||||
ztd::option('R', "no-resolve", false, "Don't resolve %resolve commands"),
|
ztd::option('R', "no-resolve", false, "Don't resolve %resolve commands"),
|
||||||
ztd::option("no-extend", false, "Don't add lxsh extension functions"),
|
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("debashify", false, "Attempt to turn a bash-specific script into a POSIX shell script"),
|
||||||
ztd::option("\r [var/fct processing]"),
|
ztd::option("remove-unused", false, "Remove unused functions and variables"),
|
||||||
ztd::option("minify-var", false, "Minify variable names"),
|
ztd::option("list-cmd", false, "List all commands invoked in the script"),
|
||||||
ztd::option("minify-fct", false, "Minify function names"),
|
ztd::option("\r [Variable processing]"),
|
||||||
ztd::option("exclude-var", true, "List of matching regex to ignore for variable processing", "list"),
|
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("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", 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-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-var-call", false, "List all variables invoked in the script"),
|
||||||
ztd::option("list-fct", false, "List all functions defined in the script"),
|
ztd::option("unset-var", false, "Add 'unset' to all variables at the start of the script to avoid environment interference"),
|
||||||
ztd::option("list-cmd", false, "List all commands invoked in the script"),
|
ztd::option("\r [Function processing]"),
|
||||||
ztd::option("remove-unused", false, "Remove unused functions and variables"),
|
ztd::option("exclude-fct", true, "List of matching regex to ignore for function processing", "list"),
|
||||||
ztd::option("unset-var", false, "Add 'unset' to all vars at the start of the script to avoid environment interference")
|
ztd::option("minify-fct", false, "Minify function names"),
|
||||||
|
ztd::option("list-fct", false, "List all functions defined in the script")
|
||||||
} );
|
} );
|
||||||
|
|
||||||
bool g_cd=false;
|
bool g_cd=false;
|
||||||
|
|
@ -96,9 +97,8 @@ ztd::option_set create_resolve_opts()
|
||||||
void print_help(const char* arg0)
|
void print_help(const char* arg0)
|
||||||
{
|
{
|
||||||
printf("%s [options] <file> [arg...]\n", arg0);
|
printf("%s [options] <file> [arg...]\n", arg0);
|
||||||
printf("Link extended shell\n");
|
printf("Extended shell linker\n");
|
||||||
printf("Include files and resolve commands on build time\n");
|
printf("Include files, resolve commands on build time, process and minify shell code\n");
|
||||||
printf("See --help-commands for help on linker commands\n");
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("Options:\n");
|
printf("Options:\n");
|
||||||
options.print_help(4,25);
|
options.print_help(4,25);
|
||||||
|
|
|
||||||
|
|
@ -41,13 +41,15 @@ std::string unexpected_token(std::string const& s)
|
||||||
|
|
||||||
void parse_error(std::string const& message, parse_context& ctx)
|
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;
|
ctx.has_errored=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_error(std::string const& message, parse_context& ctx, uint64_t i)
|
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;
|
ctx.has_errored=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#include "struc_helper.hpp"
|
#include "struc_helper.hpp"
|
||||||
|
|
||||||
const std::map<const std::string, const lxsh_fct> lxsh_extend_fcts = {
|
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_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"} } }
|
{ "_lxsh_random_tmpfile", { "[N]", "Get a random TMP filepath, with N random chars. Default 20", RANDOM_TMPFILE_SH, {"_lxsh_random_string"} } }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
73
src/util.cpp
73
src/util.cpp
|
|
@ -10,6 +10,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include <ztd/shell.hpp>
|
#include <ztd/shell.hpp>
|
||||||
|
#include <ztd/color.hpp>
|
||||||
|
|
||||||
std::string indenting_string="\t";
|
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)
|
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)
|
uint64_t index = e.where();
|
||||||
{
|
|
||||||
int i=0, j=0; // j: last newline
|
uint64_t i=0, j=0; // j: last newline
|
||||||
int line=1; //n: line #
|
uint64_t line=1; //n: line #
|
||||||
int in_size=strlen(in);
|
uint64_t in_size=strlen(in);
|
||||||
if(index >= 0)
|
if(index >= 0)
|
||||||
{
|
{
|
||||||
while(i < in_size && i < index)
|
while(i < in_size && i < index)
|
||||||
|
|
@ -233,56 +233,25 @@ void printErrorIndex(const char* in, const int index, const std::string& message
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
while(i < in_size && in[i]!='\n')
|
while(i < in_size && in[i]!='\n')
|
||||||
{
|
|
||||||
i++;
|
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)
|
if(print_line)
|
||||||
{
|
{
|
||||||
std::cerr << std::string(in+j, i-j) << std::endl;
|
std::cerr << std::string(in+j, i-j) << std::endl;
|
||||||
std::cerr << repeatString(" ", index-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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue