diff options
Diffstat (limited to 'xs/src/avrdude')
-rw-r--r-- | xs/src/avrdude/CMakeLists.txt | 114 | ||||
-rw-r--r-- | xs/src/avrdude/Makefile.standalone | 54 | ||||
-rw-r--r-- | xs/src/avrdude/avrdude-slic3r.cpp | 118 | ||||
-rw-r--r-- | xs/src/avrdude/avrdude-slic3r.hpp | 24 | ||||
-rw-r--r-- | xs/src/avrdude/avrdude.h | 6 | ||||
-rw-r--r-- | xs/src/avrdude/avrpart.c | 34 | ||||
-rw-r--r-- | xs/src/avrdude/buspirate.c | 7 | ||||
-rw-r--r-- | xs/src/avrdude/butterfly.c | 7 | ||||
-rw-r--r-- | xs/src/avrdude/fileio.c | 56 | ||||
-rw-r--r-- | xs/src/avrdude/lexer.c | 8 | ||||
-rw-r--r-- | xs/src/avrdude/libavrdude.h | 6 | ||||
-rw-r--r-- | xs/src/avrdude/main-standalone.c | 9 | ||||
-rw-r--r-- | xs/src/avrdude/main.c | 29 | ||||
-rw-r--r-- | xs/src/avrdude/pgm.c | 7 | ||||
-rw-r--r-- | xs/src/avrdude/ser_win32.c | 11 | ||||
-rw-r--r-- | xs/src/avrdude/stk500v2.c | 7 | ||||
-rw-r--r-- | xs/src/avrdude/update.c | 45 | ||||
-rw-r--r-- | xs/src/avrdude/wiring.c | 7 |
18 files changed, 399 insertions, 150 deletions
diff --git a/xs/src/avrdude/CMakeLists.txt b/xs/src/avrdude/CMakeLists.txt index 043f8fb7b..d88563368 100644 --- a/xs/src/avrdude/CMakeLists.txt +++ b/xs/src/avrdude/CMakeLists.txt @@ -1,3 +1,4 @@ +cmake_minimum_required(VERSION 3.0) add_definitions(-D_BSD_SOURCE -D_DEFAULT_SOURCE) # To enable various useful macros and functions on Unices @@ -13,67 +14,74 @@ endif() set(AVRDUDE_SOURCES - ${LIBDIR}/avrdude/arduino.c - ${LIBDIR}/avrdude/avr.c - # ${LIBDIR}/avrdude/avrftdi.c - # ${LIBDIR}/avrdude/avrftdi_tpi.c - ${LIBDIR}/avrdude/avrpart.c - ${LIBDIR}/avrdude/avr910.c - ${LIBDIR}/avrdude/bitbang.c - ${LIBDIR}/avrdude/buspirate.c - ${LIBDIR}/avrdude/butterfly.c - ${LIBDIR}/avrdude/config.c - ${LIBDIR}/avrdude/config_gram.c - # ${LIBDIR}/avrdude/confwin.c - ${LIBDIR}/avrdude/crc16.c - # ${LIBDIR}/avrdude/dfu.c - ${LIBDIR}/avrdude/fileio.c - # ${LIBDIR}/avrdude/flip1.c - # ${LIBDIR}/avrdude/flip2.c - # ${LIBDIR}/avrdude/ft245r.c - # ${LIBDIR}/avrdude/jtagmkI.c - # ${LIBDIR}/avrdude/jtagmkII.c - # ${LIBDIR}/avrdude/jtag3.c - ${LIBDIR}/avrdude/lexer.c - ${LIBDIR}/avrdude/linuxgpio.c - ${LIBDIR}/avrdude/lists.c - # ${LIBDIR}/avrdude/par.c - ${LIBDIR}/avrdude/pgm.c - ${LIBDIR}/avrdude/pgm_type.c - ${LIBDIR}/avrdude/pickit2.c - ${LIBDIR}/avrdude/pindefs.c - # ${LIBDIR}/avrdude/ppi.c - # ${LIBDIR}/avrdude/ppiwin.c - ${LIBDIR}/avrdude/safemode.c - ${LIBDIR}/avrdude/ser_avrdoper.c - ${LIBDIR}/avrdude/serbb_posix.c - ${LIBDIR}/avrdude/serbb_win32.c - ${LIBDIR}/avrdude/ser_posix.c - ${LIBDIR}/avrdude/ser_win32.c - ${LIBDIR}/avrdude/stk500.c - ${LIBDIR}/avrdude/stk500generic.c - ${LIBDIR}/avrdude/stk500v2.c - ${LIBDIR}/avrdude/term.c - ${LIBDIR}/avrdude/update.c - # ${LIBDIR}/avrdude/usbasp.c - # ${LIBDIR}/avrdude/usb_hidapi.c - # ${LIBDIR}/avrdude/usb_libusb.c - # ${LIBDIR}/avrdude/usbtiny.c - ${LIBDIR}/avrdude/wiring.c + arduino.c + avr.c + # avrftdi.c + # avrftdi_tpi.c + avrpart.c + avr910.c + bitbang.c + buspirate.c + butterfly.c + config.c + config_gram.c + # confwin.c + crc16.c + # dfu.c + fileio.c + # flip1.c + # flip2.c + # ft245r.c + # jtagmkI.c + # jtagmkII.c + # jtag3.c + lexer.c + linuxgpio.c + lists.c + # par.c + pgm.c + pgm_type.c + pickit2.c + pindefs.c + # ppi.c + # ppiwin.c + safemode.c + ser_avrdoper.c + serbb_posix.c + serbb_win32.c + ser_posix.c + ser_win32.c + stk500.c + stk500generic.c + stk500v2.c + term.c + update.c + # usbasp.c + # usb_hidapi.c + # usb_libusb.c + # usbtiny.c + wiring.c - ${LIBDIR}/avrdude/main.c - ${LIBDIR}/avrdude/avrdude-slic3r.hpp - ${LIBDIR}/avrdude/avrdude-slic3r.cpp + main.c + avrdude-slic3r.hpp + avrdude-slic3r.cpp ) if (WIN32) set(AVRDUDE_SOURCES ${AVRDUDE_SOURCES} - ${LIBDIR}/avrdude/windows/unistd.cpp - ${LIBDIR}/avrdude/windows/getopt.c + windows/unistd.cpp + windows/getopt.c ) endif() add_library(avrdude STATIC ${AVRDUDE_SOURCES}) +set(STANDALONE_SOURCES + main-standalone.c +) +add_executable(avrdude-slic3r ${STANDALONE_SOURCES}) +target_link_libraries(avrdude-slic3r avrdude) +set_target_properties(avrdude-slic3r PROPERTIES EXCLUDE_FROM_ALL TRUE) + if (WIN32) target_compile_definitions(avrdude PRIVATE WIN32NATIVE=1) - target_include_directories(avrdude SYSTEM PRIVATE ${LIBDIR}/avrdude/windows) # So that sources find the getopt.h windows drop-in + target_include_directories(avrdude SYSTEM PRIVATE windows) # So that sources find the getopt.h windows drop-in endif() diff --git a/xs/src/avrdude/Makefile.standalone b/xs/src/avrdude/Makefile.standalone new file mode 100644 index 000000000..d9a773771 --- /dev/null +++ b/xs/src/avrdude/Makefile.standalone @@ -0,0 +1,54 @@ + +TARGET = avrdude-slic3r + +SOURCES = \ + arduino.c \ + avr.c \ + avrpart.c \ + avr910.c \ + bitbang.c \ + buspirate.c \ + butterfly.c \ + config.c \ + config_gram.c \ + crc16.c \ + fileio.c \ + lexer.c \ + linuxgpio.c \ + lists.c \ + pgm.c \ + pgm_type.c \ + pickit2.c \ + pindefs.c \ + safemode.c \ + ser_avrdoper.c \ + serbb_posix.c \ + serbb_win32.c \ + ser_posix.c \ + ser_win32.c \ + stk500.c \ + stk500generic.c \ + stk500v2.c \ + term.c \ + update.c \ + wiring.c \ + main.c \ + main-standalone.c + +OBJECTS = $(SOURCES:.c=.o) +CFLAGS = -std=c99 -Wall -D_BSD_SOURCE -D_DEFAULT_SOURCE -O3 -DNDEBUG -fPIC +LDFLAGS = -lm + +CC = gcc +RM = rm + +all: $(TARGET) + +$(TARGET): $(OBJECTS) + $(CC) -o ./$@ $(OBJECTS) $(LDFLAGS) + +$(OBJECTS): %.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + +clean: + $(RM) -f $(OBJECTS) $(TARGET) diff --git a/xs/src/avrdude/avrdude-slic3r.cpp b/xs/src/avrdude/avrdude-slic3r.cpp index 030353413..3037f5284 100644 --- a/xs/src/avrdude/avrdude-slic3r.cpp +++ b/xs/src/avrdude/avrdude-slic3r.cpp @@ -2,6 +2,10 @@ #include <deque> #include <thread> +#include <cstring> +#include <cstdlib> +#include <new> +#include <exception> extern "C" { #include "ac_cfg.h" @@ -28,6 +32,11 @@ static void avrdude_progress_handler_closure(const char *task, unsigned progress (*progress_fn)(task, progress); } +static void avrdude_oom_handler(const char *context, void *user_p) +{ + throw std::bad_alloc(); +} + // Private @@ -35,6 +44,8 @@ struct AvrDude::priv { std::string sys_config; std::deque<std::vector<std::string>> args; + bool cancelled = false; + int exit_code = 0; size_t current_args_set = 0; RunFn run_fn; MessageFn message_fn; @@ -45,16 +56,22 @@ struct AvrDude::priv priv(std::string &&sys_config) : sys_config(sys_config) {} + void set_handlers(); + void unset_handlers(); int run_one(const std::vector<std::string> &args); int run(); -}; -int AvrDude::priv::run_one(const std::vector<std::string> &args) { - std::vector<char*> c_args {{ const_cast<char*>(PACKAGE_NAME) }}; - for (const auto &arg : args) { - c_args.push_back(const_cast<char*>(arg.data())); - } + struct HandlerGuard + { + priv &p; + + HandlerGuard(priv &p) : p(p) { p.set_handlers(); } + ~HandlerGuard() { p.unset_handlers(); } + }; +}; +void AvrDude::priv::set_handlers() +{ if (message_fn) { ::avrdude_message_handler_set(avrdude_message_handler_closure, reinterpret_cast<void*>(&message_fn)); } else { @@ -67,10 +84,27 @@ int AvrDude::priv::run_one(const std::vector<std::string> &args) { ::avrdude_progress_handler_set(nullptr, nullptr); } - const auto res = ::avrdude_main(static_cast<int>(c_args.size()), c_args.data(), sys_config.c_str()); + ::avrdude_oom_handler_set(avrdude_oom_handler, nullptr); +} +void AvrDude::priv::unset_handlers() +{ ::avrdude_message_handler_set(nullptr, nullptr); ::avrdude_progress_handler_set(nullptr, nullptr); + ::avrdude_oom_handler_set(nullptr, nullptr); +} + + +int AvrDude::priv::run_one(const std::vector<std::string> &args) { + std::vector<char*> c_args {{ const_cast<char*>(PACKAGE_NAME) }}; + for (const auto &arg : args) { + c_args.push_back(const_cast<char*>(arg.data())); + } + + HandlerGuard guard(*this); + + const auto res = ::avrdude_main(static_cast<int>(c_args.size()), c_args.data(), sys_config.c_str()); + return res; } @@ -132,7 +166,7 @@ AvrDude& AvrDude::on_complete(CompleteFn fn) int AvrDude::run_sync() { - return p->run(); + return p ? p->run() : -1; } AvrDude::Ptr AvrDude::run() @@ -141,14 +175,46 @@ AvrDude::Ptr AvrDude::run() if (self->p) { auto avrdude_thread = std::thread([self]() { - if (self->p->run_fn) { - self->p->run_fn(); - } - - auto res = self->p->run(); - - if (self->p->complete_fn) { - self->p->complete_fn(res, self->p->current_args_set); + try { + if (self->p->run_fn) { + self->p->run_fn(self); + } + + if (! self->p->cancelled) { + self->p->exit_code = self->p->run(); + } + + if (self->p->complete_fn) { + self->p->complete_fn(); + } + } catch (const std::exception &ex) { + self->p->exit_code = EXIT_EXCEPTION; + + static const char *msg = "An exception was thrown in the background thread:\n"; + + const char *what = ex.what(); + auto &message_fn = self->p->message_fn; + if (message_fn) { + message_fn(msg, sizeof(msg)); + message_fn(what, std::strlen(what)); + message_fn("\n", 1); + } + + if (self->p->complete_fn) { + self->p->complete_fn(); + } + } catch (...) { + self->p->exit_code = EXIT_EXCEPTION; + + static const char *msg = "An unkown exception was thrown in the background thread.\n"; + + if (self->p->message_fn) { + self->p->message_fn(msg, sizeof(msg)); + } + + if (self->p->complete_fn) { + self->p->complete_fn(); + } } }); @@ -160,7 +226,10 @@ AvrDude::Ptr AvrDude::run() void AvrDude::cancel() { - ::avrdude_cancel(); + if (p) { + p->cancelled = true; + ::avrdude_cancel(); + } } void AvrDude::join() @@ -170,5 +239,20 @@ void AvrDude::join() } } +bool AvrDude::cancelled() +{ + return p ? p->cancelled : false; +} + +int AvrDude::exit_code() +{ + return p ? p->exit_code : 0; +} + +size_t AvrDude::last_args_set() +{ + return p ? p->current_args_set : 0; +} + } diff --git a/xs/src/avrdude/avrdude-slic3r.hpp b/xs/src/avrdude/avrdude-slic3r.hpp index 273aa2378..754e1e345 100644 --- a/xs/src/avrdude/avrdude-slic3r.hpp +++ b/xs/src/avrdude/avrdude-slic3r.hpp @@ -11,11 +11,16 @@ namespace Slic3r { class AvrDude { public: + enum { + EXIT_SUCCEESS = 0, + EXIT_EXCEPTION = -1000, + }; + typedef std::shared_ptr<AvrDude> Ptr; - typedef std::function<void()> RunFn; + typedef std::function<void(Ptr /* avrdude */)> RunFn; typedef std::function<void(const char * /* msg */, unsigned /* size */)> MessageFn; typedef std::function<void(const char * /* task */, unsigned /* progress */)> ProgressFn; - typedef std::function<void(int /* exit status */, size_t /* args_id */)> CompleteFn; + typedef std::function<void()> CompleteFn; // Main c-tor, sys_config is the location of avrdude's main configuration file AvrDude(std::string sys_config); @@ -31,7 +36,8 @@ public: AvrDude& push_args(std::vector<std::string> args); // Set a callback to be called just after run() before avrdude is ran - // This can be used to perform any needed setup tasks from the background thread. + // This can be used to perform any needed setup tasks from the background thread, + // and, optionally, to cancel by writing true to the `cancel` argument. // This has no effect when using run_sync(). AvrDude& on_run(RunFn fn); @@ -48,11 +54,23 @@ public: // This has no effect when using run_sync(). AvrDude& on_complete(CompleteFn fn); + // Perform AvrDude invocation(s) synchronously on the current thread int run_sync(); + + // Perform AvrDude invocation(s) on a background thread. + // Current instance is moved into a shared_ptr which is returned (and also passed in on_run, if any). Ptr run(); + // Cancel current operation void cancel(); + + // If there is a background thread and it is joinable, join() it, + // that is, wait for it to finish. void join(); + + bool cancelled(); // Whether avrdude run was cancelled + int exit_code(); // The exit code of the last invocation + size_t last_args_set(); // Index of the last argument set that was processsed private: struct priv; std::unique_ptr<priv> p; diff --git a/xs/src/avrdude/avrdude.h b/xs/src/avrdude/avrdude.h index 9f724433f..f4c92a75d 100644 --- a/xs/src/avrdude/avrdude.h +++ b/xs/src/avrdude/avrdude.h @@ -39,6 +39,12 @@ typedef void (*avrdude_progress_handler_t)(const char *task, unsigned progress, void avrdude_progress_handler_set(avrdude_progress_handler_t newhandler, void *user_p); void avrdude_progress_external(const char *task, unsigned progress); +// OOM handler +typedef void (*avrdude_oom_handler_t)(const char *context, void *user_p); +void avrdude_oom_handler_set(avrdude_oom_handler_t newhandler, void *user_p); +void avrdude_oom(const char *context); + + // Cancellation void avrdude_cancel(); diff --git a/xs/src/avrdude/avrpart.c b/xs/src/avrdude/avrpart.c index b04851ac1..d0bb951ee 100644 --- a/xs/src/avrdude/avrpart.c +++ b/xs/src/avrdude/avrpart.c @@ -36,8 +36,9 @@ OPCODE * avr_new_opcode(void) m = (OPCODE *)malloc(sizeof(*m)); if (m == NULL) { - avrdude_message(MSG_INFO, "avr_new_opcode(): out of memory\n"); - exit(1); + // avrdude_message(MSG_INFO, "avr_new_opcode(): out of memory\n"); + // exit(1); + avrdude_oom("avr_new_opcode(): out of memory\n"); } memset(m, 0, sizeof(*m)); @@ -56,8 +57,9 @@ static OPCODE * avr_dup_opcode(OPCODE * op) m = (OPCODE *)malloc(sizeof(*m)); if (m == NULL) { - avrdude_message(MSG_INFO, "avr_dup_opcode(): out of memory\n"); - exit(1); + // avrdude_message(MSG_INFO, "avr_dup_opcode(): out of memory\n"); + // exit(1); + avrdude_oom("avr_dup_opcode(): out of memory\n"); } memcpy(m, op, sizeof(*m)); @@ -249,8 +251,9 @@ AVRMEM * avr_new_memtype(void) m = (AVRMEM *)malloc(sizeof(*m)); if (m == NULL) { - avrdude_message(MSG_INFO, "avr_new_memtype(): out of memory\n"); - exit(1); + // avrdude_message(MSG_INFO, "avr_new_memtype(): out of memory\n"); + // exit(1); + avrdude_oom("avr_new_memtype(): out of memory\n"); } memset(m, 0, sizeof(*m)); @@ -300,9 +303,10 @@ AVRMEM * avr_dup_mem(AVRMEM * m) if (m->buf != NULL) { n->buf = (unsigned char *)malloc(n->size); if (n->buf == NULL) { - avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n", - n->size); - exit(1); + // avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n", + // n->size); + // exit(1); + avrdude_oom("avr_dup_mem(): out of memory"); } memcpy(n->buf, m->buf, n->size); } @@ -310,9 +314,10 @@ AVRMEM * avr_dup_mem(AVRMEM * m) if (m->tags != NULL) { n->tags = (unsigned char *)malloc(n->size); if (n->tags == NULL) { - avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n", - n->size); - exit(1); + // avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n", + // n->size); + // exit(1); + avrdude_oom("avr_dup_mem(): out of memory"); } memcpy(n->tags, m->tags, n->size); } @@ -441,8 +446,9 @@ AVRPART * avr_new_part(void) p = (AVRPART *)malloc(sizeof(AVRPART)); if (p == NULL) { - avrdude_message(MSG_INFO, "new_part(): out of memory\n"); - exit(1); + // avrdude_message(MSG_INFO, "new_part(): out of memory\n"); + // exit(1); + avrdude_oom("new_part(): out of memory\n"); } memset(p, 0, sizeof(*p)); diff --git a/xs/src/avrdude/buspirate.c b/xs/src/avrdude/buspirate.c index 435c4ce53..5875d4283 100644 --- a/xs/src/avrdude/buspirate.c +++ b/xs/src/avrdude/buspirate.c @@ -1135,9 +1135,10 @@ static void buspirate_setup(struct programmer_t *pgm) { /* Allocate private data */ if ((pgm->cookie = calloc(1, sizeof(struct pdata))) == 0) { - avrdude_message(MSG_INFO, "%s: buspirate_initpgm(): Out of memory allocating private data\n", - progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: buspirate_initpgm(): Out of memory allocating private data\n", + // progname); + // exit(1); + avrdude_oom("buspirate_initpgm(): Out of memory allocating private data\n"); } PDATA(pgm)->serial_recv_timeout = 100; } diff --git a/xs/src/avrdude/butterfly.c b/xs/src/avrdude/butterfly.c index de9a3175f..beb5e04de 100644 --- a/xs/src/avrdude/butterfly.c +++ b/xs/src/avrdude/butterfly.c @@ -63,9 +63,10 @@ struct pdata static void butterfly_setup(PROGRAMMER * pgm) { if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - avrdude_message(MSG_INFO, "%s: butterfly_setup(): Out of memory allocating private data\n", - progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: butterfly_setup(): Out of memory allocating private data\n", + // progname); + // exit(1); + avrdude_oom("butterfly_setup(): Out of memory allocating private data\n"); } memset(pgm->cookie, 0, sizeof(struct pdata)); } diff --git a/xs/src/avrdude/fileio.c b/xs/src/avrdude/fileio.c index aa57f5587..708159295 100644 --- a/xs/src/avrdude/fileio.c +++ b/xs/src/avrdude/fileio.c @@ -98,11 +98,11 @@ static int fileio_num(struct fioparms * fio, char * filename, FILE * f, AVRMEM * mem, int size, FILEFMT fmt); -static int fmt_autodetect(char * fname, size_t offset); +static int fmt_autodetect(char * fname, unsigned section); -static FILE *fopen_and_seek(const char *filename, const char *mode, size_t offset) +static FILE *fopen_and_seek(const char *filename, const char *mode, unsigned section) { FILE *file; // On Windows we need to convert the filename to UTF-16 @@ -118,16 +118,38 @@ static FILE *fopen_and_seek(const char *filename, const char *mode, size_t offse file = fopen(filename, mode); #endif - if (file != NULL) { - // Some systems allow seeking past the end of file, so we need check for that first and disallow - if (fseek(file, 0, SEEK_END) != 0 - || offset >= ftell(file) - || fseek(file, offset, SEEK_SET) != 0 - ) { - fclose(file); - file = NULL; - errno = EINVAL; + if (file == NULL) { + return NULL; + } + + // Seek to the specified 'section' + static const char *hex_terminator = ":00000001FF\r"; + unsigned terms_seen = 0; + char buffer[MAX_LINE_LEN + 1]; + + while (terms_seen < section && fgets(buffer, MAX_LINE_LEN, file) != NULL) { + size_t len = strlen(buffer); + + if (buffer[len - 1] == '\n') { + len--; + buffer[len] = 0; + } + if (buffer[len - 1] != '\r') { + buffer[len] = '\r'; + len++; + buffer[len] = 0; } + + if (strcmp(buffer, hex_terminator) == 0) { + // Found a section terminator + terms_seen++; + } + } + + if (feof(file)) { + // Section not found + fclose(file); + return NULL; } return file; @@ -1392,7 +1414,7 @@ int fileio_setparms(int op, struct fioparms * fp, -static int fmt_autodetect(char * fname, size_t offset) +static int fmt_autodetect(char * fname, unsigned section) { FILE * f; unsigned char buf[MAX_LINE_LEN]; @@ -1402,9 +1424,9 @@ static int fmt_autodetect(char * fname, size_t offset) int first = 1; #if defined(WIN32NATIVE) - f = fopen_and_seek(fname, "r", offset); + f = fopen_and_seek(fname, "r", section); #else - f = fopen_and_seek(fname, "rb", offset); + f = fopen_and_seek(fname, "rb", section); #endif if (f == NULL) { @@ -1480,7 +1502,7 @@ static int fmt_autodetect(char * fname, size_t offset) int fileio(int op, char * filename, FILEFMT format, - struct avrpart * p, char * memtype, int size, size_t offset) + struct avrpart * p, char * memtype, int size, unsigned section) { int rc; FILE * f; @@ -1539,7 +1561,7 @@ int fileio(int op, char * filename, FILEFMT format, return -1; } - format_detect = fmt_autodetect(fname, offset); + format_detect = fmt_autodetect(fname, section); if (format_detect < 0) { avrdude_message(MSG_INFO, "%s: can't determine file format for %s, specify explicitly\n", progname, fname); @@ -1570,7 +1592,7 @@ int fileio(int op, char * filename, FILEFMT format, if (format != FMT_IMM) { if (!using_stdio) { - f = fopen_and_seek(fname, fio.mode, offset); + f = fopen_and_seek(fname, fio.mode, section); if (f == NULL) { avrdude_message(MSG_INFO, "%s: can't open %s file %s: %s\n", progname, fio.iodesc, fname, strerror(errno)); diff --git a/xs/src/avrdude/lexer.c b/xs/src/avrdude/lexer.c index 93249a9ab..f2d8adb4b 100644 --- a/xs/src/avrdude/lexer.c +++ b/xs/src/avrdude/lexer.c @@ -2834,7 +2834,8 @@ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n ); if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + // YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + avrdude_oom("out of dynamic memory in yy_scan_bytes()"); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; @@ -2859,8 +2860,9 @@ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) static void yynoreturn yy_fatal_error (const char* msg ) { - fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); + fprintf( stderr, "%s\n", msg ); + // exit( YY_EXIT_FAILURE ); + abort(); } /* Redefine yyless() so it works in section 3 code. */ diff --git a/xs/src/avrdude/libavrdude.h b/xs/src/avrdude/libavrdude.h index 536f1a2f7..aef792476 100644 --- a/xs/src/avrdude/libavrdude.h +++ b/xs/src/avrdude/libavrdude.h @@ -821,7 +821,7 @@ extern "C" { char * fmtstr(FILEFMT format); int fileio(int op, char * filename, FILEFMT format, - struct avrpart * p, char * memtype, int size, size_t offset); + struct avrpart * p, char * memtype, int size, unsigned section); #ifdef __cplusplus } @@ -870,7 +870,7 @@ enum updateflags { typedef struct update_t { char * memtype; int op; - size_t offset; + unsigned section; char * filename; int format; } UPDATE; @@ -882,7 +882,7 @@ extern "C" { extern UPDATE * parse_op(char * s); extern UPDATE * dup_update(UPDATE * upd); extern UPDATE * new_update(int op, char * memtype, int filefmt, - char * filename, size_t offset); + char * filename, unsigned section); extern void free_update(UPDATE * upd); extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags flags); diff --git a/xs/src/avrdude/main-standalone.c b/xs/src/avrdude/main-standalone.c new file mode 100644 index 000000000..359a055ca --- /dev/null +++ b/xs/src/avrdude/main-standalone.c @@ -0,0 +1,9 @@ +#include "avrdude.h" + + +static const char* SYS_CONFIG = "/etc/avrdude-slic3r.conf"; + +int main(int argc, char *argv[]) +{ + return avrdude_main(argc, argv, SYS_CONFIG); +} diff --git a/xs/src/avrdude/main.c b/xs/src/avrdude/main.c index d4c34fe44..ebda0ba19 100644 --- a/xs/src/avrdude/main.c +++ b/xs/src/avrdude/main.c @@ -144,6 +144,33 @@ void avrdude_progress_external(const char *task, unsigned progress) avrdude_progress_handler(task, progress, avrdude_progress_handler_user_p); } +static void avrdude_oom_handler_null(const char *context, void *user_p) +{ + // Output a message and just exit + fputs("avrdude: Out of memory: ", stderr); + fputs(context, stderr); + exit(99); +} + +static void *avrdude_oom_handler_user_p = NULL; +static avrdude_oom_handler_t avrdude_oom_handler = avrdude_oom_handler_null; + +void avrdude_oom_handler_set(avrdude_oom_handler_t newhandler, void *user_p) +{ + if (newhandler != NULL) { + avrdude_oom_handler = newhandler; + avrdude_oom_handler_user_p = user_p; + } else { + avrdude_oom_handler = avrdude_oom_handler_null; + avrdude_oom_handler_user_p = NULL; + } +} + +void avrdude_oom(const char *context) +{ + avrdude_oom_handler(context, avrdude_oom_handler_user_p); +} + void avrdude_cancel() { cancel_flag = true; @@ -194,7 +221,7 @@ static void usage(void) " -F Override invalid signature check.\n" " -e Perform a chip erase.\n" " -O Perform RC oscillator calibration (see AVR053). \n" - " -U <memtype>:r|w|v:<offset>:<filename>[:format]\n" + " -U <memtype>:r|w|v:<section>:<filename>[:format]\n" " Memory operation specification.\n" " Multiple -U options are allowed, each request\n" " is performed in the order specified.\n" diff --git a/xs/src/avrdude/pgm.c b/xs/src/avrdude/pgm.c index 851ac5a87..b8a93f104 100644 --- a/xs/src/avrdude/pgm.c +++ b/xs/src/avrdude/pgm.c @@ -172,9 +172,10 @@ PROGRAMMER * pgm_dup(const PROGRAMMER * const src) for (ln = lfirst(src->usbpid); ln; ln = lnext(ln)) { int *ip = malloc(sizeof(int)); if (ip == NULL) { - avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n", - progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n", + // progname); + // exit(1); + avrdude_oom("out of memory allocating programmer structure\n"); } *ip = *(int *) ldata(ln); ladd(pgm->usbpid, ip); diff --git a/xs/src/avrdude/ser_win32.c b/xs/src/avrdude/ser_win32.c index 20d085d13..4e1713128 100644 --- a/xs/src/avrdude/ser_win32.c +++ b/xs/src/avrdude/ser_win32.c @@ -246,10 +246,11 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp) newname = malloc(strlen("\\\\.\\") + strlen(port) + 1); if (newname == 0) { - avrdude_message(MSG_INFO, "%s: ser_open(): out of memory\n", - progname); - exit(1); - } + // avrdude_message(MSG_INFO, "%s: ser_open(): out of memory\n", + // progname); + // exit(1); + avrdude_oom("ser_open(): out of memory\n"); + } strcpy(newname, "\\\\.\\"); strcat(newname, port); @@ -311,8 +312,10 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp) static void ser_close(union filedescriptor *fd) { if (serial_over_ethernet) { +#ifdef HAVE_LIBWS2_32 closesocket(fd->ifd); WSACleanup(); +#endif } else { HANDLE hComPort=(HANDLE)fd->pfd; if (hComPort != INVALID_HANDLE_VALUE) diff --git a/xs/src/avrdude/stk500v2.c b/xs/src/avrdude/stk500v2.c index 4d62640c0..691152b46 100644 --- a/xs/src/avrdude/stk500v2.c +++ b/xs/src/avrdude/stk500v2.c @@ -295,9 +295,10 @@ static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p); void stk500v2_setup(PROGRAMMER * pgm) { if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - avrdude_message(MSG_INFO, "%s: stk500v2_setup(): Out of memory allocating private data\n", - progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: stk500v2_setup(): Out of memory allocating private data\n", + // progname); + // exit(1); + avrdude_oom("stk500v2_setup(): Out of memory allocating private data\n"); } memset(pgm->cookie, 0, sizeof(struct pdata)); PDATA(pgm)->command_sequence = 1; diff --git a/xs/src/avrdude/update.c b/xs/src/avrdude/update.c index e9dd6e325..a255ab4f9 100644 --- a/xs/src/avrdude/update.c +++ b/xs/src/avrdude/update.c @@ -38,8 +38,9 @@ UPDATE * parse_op(char * s) upd = (UPDATE *)malloc(sizeof(UPDATE)); if (upd == NULL) { - avrdude_message(MSG_INFO, "%s: out of memory\n", progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: out of memory\n", progname); + // exit(1); + avrdude_oom("parse_op: out of memory\n"); } i = 0; @@ -53,8 +54,9 @@ UPDATE * parse_op(char * s) upd->op = DEVICE_WRITE; upd->filename = (char *)malloc(strlen(buf) + 1); if (upd->filename == NULL) { - avrdude_message(MSG_INFO, "%s: out of memory\n", progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: out of memory\n", progname); + // exit(1); + avrdude_oom("parse_op: out of memory\n"); } strcpy(upd->filename, buf); upd->format = FMT_AUTO; @@ -63,8 +65,9 @@ UPDATE * parse_op(char * s) upd->memtype = (char *)malloc(strlen(buf)+1); if (upd->memtype == NULL) { - avrdude_message(MSG_INFO, "%s: out of memory\n", progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: out of memory\n", progname); + // exit(1); + avrdude_oom("parse_op: out of memory\n"); } strcpy(upd->memtype, buf); @@ -101,22 +104,22 @@ UPDATE * parse_op(char * s) p++; - // Extension: Parse file contents offset - size_t offset = 0; + // Extension: Parse file section number + unsigned section = 0; for (; *p != ':'; p++) { if (*p >= '0' && *p <= '9') { - offset *= 10; - offset += *p - 0x30; + section *= 10; + section += *p - 0x30; } else { - avrdude_message(MSG_INFO, "%s: invalid update specification: offset is not a number\n", progname); + avrdude_message(MSG_INFO, "%s: invalid update specification: <section> is not a number\n", progname); free(upd->memtype); free(upd); return NULL; } } - upd->offset = offset; + upd->section = section; p++; /* @@ -179,8 +182,9 @@ UPDATE * dup_update(UPDATE * upd) u = (UPDATE *)malloc(sizeof(UPDATE)); if (u == NULL) { - avrdude_message(MSG_INFO, "%s: out of memory\n", progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: out of memory\n", progname); + // exit(1); + avrdude_oom("dup_update: out of memory\n"); } memcpy(u, upd, sizeof(UPDATE)); @@ -194,21 +198,22 @@ UPDATE * dup_update(UPDATE * upd) return u; } -UPDATE * new_update(int op, char * memtype, int filefmt, char * filename, size_t offset) +UPDATE * new_update(int op, char * memtype, int filefmt, char * filename, unsigned section) { UPDATE * u; u = (UPDATE *)malloc(sizeof(UPDATE)); if (u == NULL) { - avrdude_message(MSG_INFO, "%s: out of memory\n", progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: out of memory\n", progname); + // exit(1); + avrdude_oom("new_update: out of memory\n"); } u->memtype = strdup(memtype); u->filename = strdup(filename); u->op = op; u->format = filefmt; - u->offset = offset; + u->section = section; return u; } @@ -286,7 +291,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f progname, strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename); } - rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->offset); + rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->section); if (rc < 0) { avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n", progname, upd->filename); @@ -351,7 +356,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f progname, mem->desc, upd->filename); } - rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->offset); + rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->section); if (rc < 0) { avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n", progname, upd->filename); diff --git a/xs/src/avrdude/wiring.c b/xs/src/avrdude/wiring.c index 395459762..562a3f17c 100644 --- a/xs/src/avrdude/wiring.c +++ b/xs/src/avrdude/wiring.c @@ -85,9 +85,10 @@ static void wiring_setup(PROGRAMMER * pgm) * Now prepare our data */ if ((mycookie = malloc(sizeof(struct wiringpdata))) == 0) { - avrdude_message(MSG_INFO, "%s: wiring_setup(): Out of memory allocating private data\n", - progname); - exit(1); + // avrdude_message(MSG_INFO, "%s: wiring_setup(): Out of memory allocating private data\n", + // progname); + // exit(1); + avrdude_oom("wiring_setup(): Out of memory allocating private data\n"); } memset(mycookie, 0, sizeof(struct wiringpdata)); WIRINGPDATA(mycookie)->snoozetime = 0; |