From cd2faf64b2e995dee42e7e3911325d372c6604a1 Mon Sep 17 00:00:00 2001 From: Oskari Timperi Date: Sun, 12 Feb 2017 17:12:52 +0200 Subject: Add all the stuff --- tools/CMakeLists.txt | 7 + tools/amalgamate.py | 90 +++++++++++++ tools/getopt.c | 358 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/getopt.h | 175 +++++++++++++++++++++++++ tools/pub.c | 96 ++++++++++++++ tools/sub.c | 103 +++++++++++++++ 6 files changed, 829 insertions(+) create mode 100644 tools/CMakeLists.txt create mode 100644 tools/amalgamate.py create mode 100644 tools/getopt.c create mode 100644 tools/getopt.h create mode 100644 tools/pub.c create mode 100644 tools/sub.c (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 0000000..1a736ab --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,7 @@ +ADD_LIBRARY(getopt OBJECT getopt.c) + +ADD_EXECUTABLE(pub pub.c $) +TARGET_LINK_LIBRARIES(pub mqtt) + +ADD_EXECUTABLE(sub sub.c $) +TARGET_LINK_LIBRARIES(sub mqtt) diff --git a/tools/amalgamate.py b/tools/amalgamate.py new file mode 100644 index 0000000..a807603 --- /dev/null +++ b/tools/amalgamate.py @@ -0,0 +1,90 @@ +import io +import os +import sys + +this_dir = os.path.dirname(os.path.abspath(__file__)) + +src_dir = os.path.join(this_dir, '..', 'src') + +sources = ( + 'queue.h', + 'log.h', + 'misc.c', + 'stringbuf.c', + 'stream.c', + 'socketstream.c', + 'stringstream.c', + 'stream_mqtt.c', + 'socket.c', + 'packet.c', + 'serialize.c', + 'deserialize.c', + 'client.c' +) + + +def is_header(filename): + return os.path.splitext(filename)[1] == '.h' + + +def get_header(src): + root, ext = os.path.splitext(src) + return root + '.h' + + +def read_file(filename): + def tounicode(s): + if sys.version_info[0] == 2: + return s.decode('utf-8') + else: + return s + with open(filename, 'r') as fp: + buf = io.StringIO() + for line in fp: + if line.startswith('#include "'): + if line[10:].startswith('mqtt.h'): + pass + else: + continue + buf.write(tounicode(line)) + return buf.getvalue() + + +def file_header(filename): + filename = os.path.basename(filename) + # how long lines we create + linelen = 72 + # how much space left after the necessary comment markup + chars = linelen - 4 + # how much padding in total for filename + padding = chars - len(filename) + padding_l = padding // 2 + padding_r = padding - padding_l + lines = ( + '', + '/*' + '*'*chars + '*/', + '/*' + ' '*padding_l + filename + ' '*padding_r + '*/', + '/*' + '*'*chars + '*/', + '\n', + ) + return '\n'.join(lines) + + +def write_file(output, srcfilename): + output.write(file_header(srcfilename)) + output.write(read_file(srcfilename)) + + +output_filename = sys.argv[1] + +with open(output_filename, 'w') as out: + for source in sources: + path = os.path.join(src_dir, source) + + if is_header(path): + write_file(out, path) + else: + header = get_header(path) + if os.path.isfile(header): + write_file(out, header) + write_file(out, path) diff --git a/tools/getopt.c b/tools/getopt.c new file mode 100644 index 0000000..5277ed0 --- /dev/null +++ b/tools/getopt.c @@ -0,0 +1,358 @@ +#include +#include +#include +#include + +#include "getopt.h" + +/* + * Standard getopt global variables. optreset starts as non-zero in order to + * trigger initialization behaviour. + */ +const char * optarg = NULL; +int optind = 1; +int opterr = 1; +int optreset = 1; + +/* + * Quasi-internal global variables -- these are used via GETOPT macros. + */ +const char * getopt_dummy = "(dummy)"; +int getopt_initialized = 0; + +/* + * Internal variables. + */ +static const char * cmdname = NULL; +static struct opt { + const char * os; + size_t olen; + int hasarg; +} * opts = NULL; +static size_t nopts; +static size_t opt_missing; +static size_t opt_default; +static size_t opt_found; +static const char * packedopts; +static char popt[3]; +static int atexit_registered = 0; + +/* Print a message. */ +#define PRINTMSG(...) do { \ + if (cmdname != NULL) \ + fprintf(stderr, "%s: ", cmdname); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ +} while (0) + +/* Print an error message and die. */ +#define DIE(...) do { \ + PRINTMSG(__VA_ARGS__); \ + abort(); \ +} while (0) + +/* Print a warning, if warnings are enabled. */ +#define WARN(...) do { \ + if (opterr == 0) \ + break; \ + if (opt_missing != opt_default) \ + break; \ + PRINTMSG(__VA_ARGS__); \ +} while (0) + +/* Free allocated options array. */ +static void +atexit_handler(void) +{ + + free(opts); + opts = NULL; +} + +/* Reset internal state. */ +static void +reset(int argc, char * const argv[]) +{ + const char * p; + + /* If we have arguments, stash argv[0] for error messages. */ + if (argc > 0) { + /* Find the basename, without leading directories. */ + for (p = cmdname = argv[0]; *p != '\0'; p++) { + if (*p == '/') + cmdname = p + 1; + } + } + + /* Discard any registered command-line options. */ + free(opts); + opts = NULL; + + /* Register atexit handler if we haven't done so already. */ + if (!atexit_registered) { + atexit(atexit_handler); + atexit_registered = 1; + } + + /* We will start scanning from the first option. */ + optind = 1; + + /* We're not in the middle of any packed options. */ + packedopts = NULL; + + /* We haven't found any option yet. */ + opt_found = (size_t)(-1); + + /* We're not initialized yet. */ + getopt_initialized = 0; + + /* Finished resetting state. */ + optreset = 0; +} + +/* Search for an option string. */ +static size_t +searchopt(const char * os) +{ + size_t i; + + /* Scan the array of options. */ + for (i = 0; i < nopts; i++) { + /* Is there an option in this slot? */ + if (opts[i].os == NULL) + continue; + + /* Does this match up to the length of the option string? */ + if (strncmp(opts[i].os, os, opts[i].olen)) + continue; + + /* Do we have